如何建立一个传统的登录表单

编辑本页

警告:您正在浏览的文档欧宝官网下载appob娱乐下载Symfony 2.5,现已不再维护。

本页的更新版本用于Syob娱乐下载mfony 6.2(当前稳定版本)。

提示

如果您需要一个登录表单,并将用户存储在某种数据库中,那么您应该考虑使用FOSUserBundle,帮助你建立你的用户对象,并为登录、注册和忘记密码等常见任务提供了许多路由和控制器。

在本文中,您将构建一个传统的登录表单。当然,当用户登录时,您可以从任何地方加载用户——比如数据库。看到安全获取详细信息。

本章假设您已经遵循了本章的开头安全章节并有http_basic认证工作正常。

首先,在防火墙下启用表单登录:

  • YAML
  • XML
  • PHP
1 2 3 4 5 6 7 8 9 10 11
# app / config / security.yml安全:#……防火墙:默认值:匿名:http_basic:form_login:login_path:/登录check_path:/ login_check

提示

login_path而且check_path也可以是路由名(但不能有强制通配符-例如。/登录/ {foo}在哪里喷火没有默认值)。

现在,当安全系统启动身份验证过程时,它将用户重定向到登录表单/登录.可视化地实现这个登录表单是您的工作。首先,创建一个新的SecurityController里面有一捆空的loginAction

12 3 4 5 6 7 8 9 10 11 12 13
/ / src / AppBundle /控制器/ SecurityController.php名称空间AppBundle控制器使用Sensio赞助FrameworkExtraBundle配置路线使用ob娱乐下载FrameworkBundle控制器控制器SecurityController扩展控制器公共函数loginAction(请求请求/ / todo……}}

接下来,创建两条路由:分别用于前面在您的目录下配置的每个路径form_login配置(/登录而且/ login_check):

  • 注释
  • YAML
  • XML
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21
/ / src / AppBundle /控制器/ SecurityController.php/ /……使用Sensio赞助FrameworkExtraBundle配置路线SecurityController扩展控制器/ * * *@Route("/login", name="login_route") */公共函数loginAction(请求请求// todo…/ * * *@Route("/login_check", name="login_check") */公共函数loginCheckAction(){}}

太棒了!接下来,将逻辑添加到loginAction将显示登录表单:

12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
/ / src / AppBundle /控制器/ SecurityController.php/ /……//在你的类上面添加THIS use语句使用ob娱乐下载组件安全核心SecurityContextInterface公共函数loginAction(请求请求会话请求->getSession ();//如果有登录错误,则获取登录错误如果请求->属性->(SecurityContextInterface::AUTHENTICATION_ERROR)) {错误请求->属性->get (SecurityContextInterface::AUTHENTICATION_ERROR);}elseif= = !会话& &会话->(SecurityContextInterface::AUTHENTICATION_ERROR)) {错误会话->get (SecurityContextInterface::AUTHENTICATION_ERROR);会话->remove (SecurityContextInterface::AUTHENTICATION_ERROR);}其他的错误;}//用户输入的最后一个用户名lastUsername= (= = =会话) ?会话->get (SecurityContextInterface::LAST_USERNAME);返回->呈现(“安全/ login.html.twig”数组//用户输入的最后一个用户名“last_username”= >lastUsername“错误”= >错误,));}

不要让这个控制器迷惑你。稍后您将看到,当用户提交表单时,安全系统将自动为您处理表单提交。如果用户提交了无效的用户名或密码,该控制器将从安全系统读取表单提交错误,以便将其显示给用户。

换句话说,你的工作就是显示登录表单和可能发生的任何登录错误,但是安全系统本身负责检查提交的用户名和密码并对用户进行身份验证。

最后,创建模板:

  • 嫩枝
  • PHP
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21 22
{# app /资源/视图/安全/ login.html。树枝#}{#……你可能会扩展你的基模板,比如base.html.twig #}{%如果错误%}<div>{{error.messageKey|trans(error.messageData)}}div>{%endif%}<形式行动{{path('login_check')}}方法“职位”><标签“用户名”>用户名:标签><输入类型“文本”id“用户名”的名字“_username”价值{{last_username}}/><标签“密码”>密码:标签><输入类型“密码”id“密码”的名字“_password”/>{#如果你想控制用户成功重定向到的URL(更多细节如下) #}<按钮类型“提交”>登录按钮>形式>

提示

错误的实例AuthenticationException.它可能包含关于身份验证失败的更多信息(甚至是敏感信息),因此要明智地使用它!

表单可以看起来像任何东西,但有几个要求:

  • 表单必须POST到/ login_check,因为这是您在form_login关键在security.yml
  • 用户名必须有名称_username密码必须有名字_password

提示

实际上,所有这些都可以在form_login关键。看到SecurityBundle配置("security")欲知详情。

谨慎

此登录表单目前没有针对CSRF攻击进行保护。读在登录表单中使用CSRF保护关于如何保护您的登录表单。

就是这样!当您提交表单时,安全系统将自动检查用户的凭据,并对用户进行身份验证,或者将用户发送回可以显示错误的登录表单。

回顾整个过程:

  1. 用户试图访问受保护的资源;
  2. 防火墙通过将用户重定向到登录表单(/登录);
  3. /登录页面通过本例中创建的路由和控制器呈现登录表单;
  4. 用户将登录表单提交给/ login_check
  5. 安全系统拦截请求,检查用户提交的凭据,验证用户是否正确,如果不正确则将用户发送回登录表单。

/登录而且/ login_check路由正确,并且它们对应于login_path而且check_path配置值。这里的错误配置可能意味着您被重定向到404页面而不是登录页面,或者提交登录表单没有任何作用(您只是一遍又一遍地看到登录表单)。

2.确保登录页面不安全(重定向循环!)

另外,请确保匿名用户可以访问登录页面。例如,下面的配置—它需要ROLE_ADMIN角色为所有url(包括/登录URL),将导致重定向循环:

  • YAML
  • XML
  • PHP
1 2 3 4 5
# app / config / security.yml#……access_control:-路径:^ /,角色:ROLE_ADMIN

添加匹配的访问控制/登录/ *并要求没有认证解决了这个问题:

  • YAML
  • XML
  • PHP
1 2 3 4 5 6
# app / config / security.yml#……access_control:-路径:^ /登录,角色:IS_AUTHENTICATED_ANONYMOUSLY-路径:^ /,角色:ROLE_ADMIN

此外,如果您的防火墙有允许匿名用户(否匿名Key),你需要创建一个特殊的防火墙,允许匿名用户登录页面:

  • YAML
  • XML
  • PHP
1 2 3 4 5 6 7 8 9 10 11
# app / config / security.yml#……防火墙:#秩序很重要!这必须在^/防火墙之前login_firewall:模式:^ /登录美元匿名:secured_area:模式:^/form_login:

3.确保/login_check位于防火墙之后

接下来,确保你的check_pathURL(例如。/ login_check)位于您用于表单登录的防火墙后面(在本例中,单个防火墙是匹配的所有url,包括/ login_check).如果/ login_check不匹配任何防火墙,你会收到无法找到路径为“/login_check”的控制器例外。

4.多个防火墙不共享安全上下文

如果您使用多个防火墙,并且针对其中一个防火墙进行身份验证,那么您就会这样做根据任何其他防火墙自动进行身份验证。不同的防火墙就像不同的安全系统。为此,您必须显式地指定相同的参数SecurityBundle配置("security")针对不同的防火墙。但通常对于大多数应用程序来说,有一个主防火墙就足够了。

5.路由错误页面不被防火墙覆盖

当路由完成时之前安全性,404错误页面不会被任何防火墙覆盖。这意味着您不能检查安全性,甚至不能访问这些页面上的用户对象。看到如何自定义错误页面欲知详情。

此工作,包括代码示例,是根据创作共用BY-SA 3.0许可证。
TOC
    版本