symfony使用security实现验证登录

来源:互联网 发布:基数排序算法 编辑:程序博客网 时间:2024/05/01 11:26

sf框架提供了一个强大的安全验证组件security,使用这个组件,可以不用写登录验证的代码,就能实现登录功能.

本文尽量用的是初学者易懂的语言来描述

具体步骤如下:

1.建立登录帐号数据表(user)

2.生成映射文件,实体类,参考http://blog.csdn.net/baby97/article/details/51248159

3.实体类需要实现UserInterface接口.以及接口中相应的抽象方法.

此处的getRoles()方法返回的固定值,可以根据实际情况,换成用户的动态权限.

getSalt()密文盐值,本例使用bcrypt加密,不需要盐值,所以返回null.

namespace CommonBundle\Entity;use Doctrine\ORM\Mapping as ORM;use Symfony\Component\Security\Core\User\UserInterface;/** * AdminUser * * @ORM\Table(name="admin_user") * @ORM\Entity(repositoryClass="CommonBundle\Repository\AdminUserRepository") */class AdminUser extends CommonEntity implements UserInterface{    public function getRoles()    {        // TODO: Implement getRoles() method.        return ['ROLE_ADMIN'];    }    public function getSalt()    {        return null;        // TODO: Implement getSalt() method.    }    public function getUsername()    {        return $this->name;        // TODO: Implement getUsername() method.    }    public function getPassword()    {        return $this->pwd;        // TODO: Implement getPassword() method.    }    public function eraseCredentials()    {        // TODO: Implement eraseCredentials() method.    }    /**     * @var integer     *     * @ORM\Column(name="id", type="integer")     * @ORM\Id     * @ORM\GeneratedValue(strategy="IDENTITY")     */    private $id;    /**     * @var string     *     * @ORM\Column(name="name", type="string", length=50, nullable=true)     */    private $name;    /**     * @var string     *     * @ORM\Column(name="pwd", type="string", length=200, nullable=true)     */    private $pwd;    /**     * Get id     *     * @return integer     */    public function getId()    {        return $this->id;    }    /**     * Set name     *     * @param string $name     *     * @return AdminUser     */    public function setName($name)    {        $this->name = $name;            return $this;    }    /**     * Get name     *     * @return string     */    public function getName()    {        return $this->name;    }    /**     * Set pwd     *     * @param string $pwd     *     * @return AdminUser     */    public function setPwd($pwd)    {        $this->pwd = $pwd;            return $this;    }    /**     * Get pwd     *     * @return string     */    public function getPwd()    {        return $this->pwd;    }}
4.配置app/config/security.yml

encoders:加密方式,此处使用bcrypt

providers:登录的实体类,property为登录用户名

firewalls:防火墙,指定了没有通过验证的地址和登录验证的地址以及登录成功后跳转地址.

access_control:设定哪些路径启动防火墙功能.IS_AUTHENTICATED_ANONYMOUSLY为允许非登录状态下访问的URL(注意:需要把/login_check设置为防火墙以外,允许非登录下访问.path为正则表达式,匹配了/login_check地址)

security:    encoders:        CommonBundle\Entity\AdminUser: bcrypt    providers:        main:            entity: { class: CommonBundle:AdminUser, property: name }    firewalls:        main:            pattern: /.*            form_login:                check_path: /login_check                login_path: /login                default_target_path: /index            logout: true            security: true            anonymous: true    access_control:        - { path: /login, role: IS_AUTHENTICATED_ANONYMOUSLY }        - { path: /.*, role: ROLE_ADMIN }

5.实现loginAction

注意下面的login_check方法,是个空的,我在看相关教程时,有的教程说login_check不用实现,系统会自动识别创建,我试过,报错.有的教程说需要建个空方法.

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;use Symfony\Bundle\FrameworkBundle\Controller\Controller;use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;use Symfony\Component\Security\Core\Security;use Symfony\Component\HttpFoundation\Request;use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;    /**     * @Route("/login",name="login_form")     * @Template()     */    public function loginAction(Request $request){        $curUser = $this->getUser();        if ($curUser) {            return $this->redirectToRoute("user_index");        }        $session = $request->getSession();        // get the login error if there is one        if ($request->attributes->has(Security::AUTHENTICATION_ERROR)) {            $error = $request->attributes->get(                Security::AUTHENTICATION_ERROR            );        } elseif (null !== $session && $session->has(Security::AUTHENTICATION_ERROR)) {            $error = $session->get(Security::AUTHENTICATION_ERROR);            $session->remove(Security::AUTHENTICATION_ERROR);        } else {            $error = '';        }        // last username entered by the user        $lastUsername = (null === $session) ? '' : $session->get(Security::LAST_USERNAME);        return array(            // last username entered by the user            'last_username' => $lastUsername,//$session->get(SecurityContextInterface::LAST_USERNAME),            'error'         => $error,        );    }    /**     * @Route("/login_check",name="login_check")     * @Method({"POST","GET"})     */    public function doLoginAction(Request $request){    }

6.建立login模板.

用户名和密码的name必须为:_username和_password

可以在配置里修改,但我没有偿试,有兴趣的可以试下.

form_login:
                login_path: /login
                check_path: /checkLogin
                default_target_path: /home
                username_parameter: _username
                password_parameter: _password
{% if error %}    <div>{{ error.message }}</div>{% endif %}<form action="{{ path('login_check') }}" method="post">    <label for="username">Username:</label>    <input type="text" id="username" name="_username" value="{{ last_username }}" />    <label for="password">Password:</label>    <input type="password" id="password" name="_password" />    {#        If you want to control the URL the user        is redirected to on success (more details below)        <input type="hidden" name="_target_path" value="/account" />    #}    <button type="submit">login</button></form>

到此,基本就实现了security方式的登录.

7.退出登录

实现退出就相对容易些,做如下配置就可以了:

security.yml

    firewalls:        main:            pattern: /.*            form_login:                check_path: /login_check                login_path: /login                default_target_path: /index            logout:                 path: /logout                target: /            security: true            anonymous: true
routing.yml

logout:    path:     /logout





0 0