Symfony 2.3 自定义表单 login_check
Symfony 2.3 custom form login_check
我已经成功创建了一个登录系统,该系统检查了一个原则用户实体 class 并成功进行了身份验证。这使用 http_basic 设置在防火墙块中:
app/config/security.yml
但是我希望使用 form_login 选项并呈现我自己的自定义登录模板。下面是 app/config/security.yml 在我进行更改以使用呈现我的自定义表单的表单登录后:
security:
encoders:
Brs\UserBundle\Entity\User:
algorithm: bcrypt
cost: 12
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
# in_memory:
# memory:
# users:
# user: { password: userpass, roles: [ 'ROLE_USER' ] }
# admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] }
administrators:
entity: { class: BrsUserBundle:User, property: fname }
firewalls:
login:
pattern: ^/admin/login$
anonymous: ~
admin_area:
pattern: ^/admin/
# http_basic: ~
form_login:
login_path: /admin/login
check_path: /admin/login_check
access_control:
- { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: ROLE_ADMIN }
现在我的表单模板发布到 security.yml 中 form_login 下定义的 check_path。
我在 LoginBundle/config/routing.yml
中的包中定义了 2 条路由
admin:
path: /admin/login
defaults: { _controller: BrsLoginBundle:Login:index }
adminlogin:
path: /admin/login_check
defaults: { _controller: BrsLoginBundle:Login:loginCheck }
admin_hello:
path: /admin/hello
defaults: { _controller: BrsLoginBundle:Login:hello }
当我提交表格时,它会 return 我到 /admin/login/ url 我似乎无法通过它进行身份验证。
根据我在 LoginController.php 中的理解,symfony 2 文档告诉我定义方法 loginCheckAction(),它是空的,return什么都没有。
如果我正确地遵循了这一点,表单将发布到 login_check 路径,并且安全系统应该像我使用 http_basic 时一样处理身份验证。
我很困惑,我目前正在再次阅读文档,看看我是否遗漏了一些愚蠢的东西。
如有任何帮助,我们将不胜感激。
亚当
编辑*
这是呈现表单的树枝模板:
{% extends 'BrsLoginBundle::layout.html.twig' %}
{% block body %}
<h1>{{ name }}</h1>
{% if error %}
<div>{{ error.messageKey|trans(error.messageData) }}</div>
{% endif %} {#{form_start(form,{ 'attr': {'novalidate': 'novalidate' }})}#}
<form action="{{ path('login_check')}}" method="post">
<input type="text" name="_username" />
<input type="password" name="_password" />
<button type="submit">Login</button>
</form>
{#{form_widget(form)}#}
{#{form_end(form)}#}
{% endblock %}
这里是控制器
<?php
namespace Brs\LoginBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Brs\LoginBundle\Form\Type\LoginType;
use Symfony\Component\Security\Core\SecurityContextInterface;
class LoginController extends Controller{
public function indexAction(Request $request){
$session = $request->getSession();
//instantiate the form type to use
//$login = new LoginType();
// create the form based on the type above
//$form = $this->createForm(new LoginType(), $login);
// this will tell me wether the form was submitted or not and handle the validation defined in bundle/resources/config/validation.yml
//$form->handleRequest($request);
//checks if the form is valid then we will execute what we want to next
//if($form->isValid()){
//do something if all validation test are passed
//}
var_dump($request->attributes->has(SecurityContextInterface::AUTHENTICATION_ERROR));
var_dump($session->has(SecurityContextInterface::AUTHENTICATION_ERROR));
var_dump(null !== $session);
$error = $session->get(SecurityContextInterface::AUTHENTICATION_ERROR);
$session->remove(SecurityContextInterface::AUTHENTICATION_ERROR);
//print_r($request->attributes->get(SecurityContextInterface::AUTHENTICATION_ERROR));
//print_r($session->get(SecurityContextInterface::AUTHENTICATION_ERROR));
//render the login template and pass the created form to it
return $this->render('BrsLoginBundle:Admin:login.html.twig',array(
'name'=>"Login",
'error'=>$error
//'form'=>$form->createView(),
));
}
public function hello(){
return new Response("i shoudlnt be able to see this");
}
public function loginCheckAction(){
}
}
?>
这是我一直关注的文档的link:
http://symfony.com/doc/2.3/cookbook/security/form_login_setup.html
编辑*
我已经跟踪了日志,这是对用户进行身份验证,但是当它调用 login_check 方法时,它会尝试从数据库重新加载用户,但找不到。所以它重新开始登录过程。日志位于下面的 link 中:
我猜是有错误
access_control:
- { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: ROLE_ADMIN }
关于访问 /admin/*
路由,您告诉 symfony 用户必须已经过身份验证。此控制在 /admin/login_check
开始他的操作之前完成。
你应该修改security.yml如下
access_control:
- { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/login_check, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: ROLE_ADMIN }
编辑
OP 声称在注销后我无法再登录。我怀疑他注销背后的逻辑不好。如果您查看他的日志,您会注意到,在第二次登录尝试后,Symfony2 报告
[2015-02-17 14:57:16] security.WARNING: Username "" could not be
found. [] []
好像没有用户名传递给 login_check 操作
我已经成功创建了一个登录系统,该系统检查了一个原则用户实体 class 并成功进行了身份验证。这使用 http_basic 设置在防火墙块中:
app/config/security.yml
但是我希望使用 form_login 选项并呈现我自己的自定义登录模板。下面是 app/config/security.yml 在我进行更改以使用呈现我的自定义表单的表单登录后:
security:
encoders:
Brs\UserBundle\Entity\User:
algorithm: bcrypt
cost: 12
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
# in_memory:
# memory:
# users:
# user: { password: userpass, roles: [ 'ROLE_USER' ] }
# admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] }
administrators:
entity: { class: BrsUserBundle:User, property: fname }
firewalls:
login:
pattern: ^/admin/login$
anonymous: ~
admin_area:
pattern: ^/admin/
# http_basic: ~
form_login:
login_path: /admin/login
check_path: /admin/login_check
access_control:
- { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: ROLE_ADMIN }
现在我的表单模板发布到 security.yml 中 form_login 下定义的 check_path。
我在 LoginBundle/config/routing.yml
中的包中定义了 2 条路由admin:
path: /admin/login
defaults: { _controller: BrsLoginBundle:Login:index }
adminlogin:
path: /admin/login_check
defaults: { _controller: BrsLoginBundle:Login:loginCheck }
admin_hello:
path: /admin/hello
defaults: { _controller: BrsLoginBundle:Login:hello }
当我提交表格时,它会 return 我到 /admin/login/ url 我似乎无法通过它进行身份验证。
根据我在 LoginController.php 中的理解,symfony 2 文档告诉我定义方法 loginCheckAction(),它是空的,return什么都没有。
如果我正确地遵循了这一点,表单将发布到 login_check 路径,并且安全系统应该像我使用 http_basic 时一样处理身份验证。
我很困惑,我目前正在再次阅读文档,看看我是否遗漏了一些愚蠢的东西。
如有任何帮助,我们将不胜感激。
亚当
编辑*
这是呈现表单的树枝模板:
{% extends 'BrsLoginBundle::layout.html.twig' %}
{% block body %}
<h1>{{ name }}</h1>
{% if error %}
<div>{{ error.messageKey|trans(error.messageData) }}</div>
{% endif %} {#{form_start(form,{ 'attr': {'novalidate': 'novalidate' }})}#}
<form action="{{ path('login_check')}}" method="post">
<input type="text" name="_username" />
<input type="password" name="_password" />
<button type="submit">Login</button>
</form>
{#{form_widget(form)}#}
{#{form_end(form)}#}
{% endblock %}
这里是控制器
<?php
namespace Brs\LoginBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Brs\LoginBundle\Form\Type\LoginType;
use Symfony\Component\Security\Core\SecurityContextInterface;
class LoginController extends Controller{
public function indexAction(Request $request){
$session = $request->getSession();
//instantiate the form type to use
//$login = new LoginType();
// create the form based on the type above
//$form = $this->createForm(new LoginType(), $login);
// this will tell me wether the form was submitted or not and handle the validation defined in bundle/resources/config/validation.yml
//$form->handleRequest($request);
//checks if the form is valid then we will execute what we want to next
//if($form->isValid()){
//do something if all validation test are passed
//}
var_dump($request->attributes->has(SecurityContextInterface::AUTHENTICATION_ERROR));
var_dump($session->has(SecurityContextInterface::AUTHENTICATION_ERROR));
var_dump(null !== $session);
$error = $session->get(SecurityContextInterface::AUTHENTICATION_ERROR);
$session->remove(SecurityContextInterface::AUTHENTICATION_ERROR);
//print_r($request->attributes->get(SecurityContextInterface::AUTHENTICATION_ERROR));
//print_r($session->get(SecurityContextInterface::AUTHENTICATION_ERROR));
//render the login template and pass the created form to it
return $this->render('BrsLoginBundle:Admin:login.html.twig',array(
'name'=>"Login",
'error'=>$error
//'form'=>$form->createView(),
));
}
public function hello(){
return new Response("i shoudlnt be able to see this");
}
public function loginCheckAction(){
}
}
?>
这是我一直关注的文档的link:
http://symfony.com/doc/2.3/cookbook/security/form_login_setup.html
编辑*
我已经跟踪了日志,这是对用户进行身份验证,但是当它调用 login_check 方法时,它会尝试从数据库重新加载用户,但找不到。所以它重新开始登录过程。日志位于下面的 link 中:
我猜是有错误
access_control:
- { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: ROLE_ADMIN }
关于访问 /admin/*
路由,您告诉 symfony 用户必须已经过身份验证。此控制在 /admin/login_check
开始他的操作之前完成。
你应该修改security.yml如下
access_control:
- { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/login_check, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: ROLE_ADMIN }
编辑
OP 声称在注销后我无法再登录。我怀疑他注销背后的逻辑不好。如果您查看他的日志,您会注意到,在第二次登录尝试后,Symfony2 报告
[2015-02-17 14:57:16] security.WARNING: Username "" could not be found. [] []
好像没有用户名传递给 login_check 操作