使用 Symfony Guard 做用户登录

使用 Symfony Guard 做用户登录

Chris Yue No Comment
Posts

其实 Symfony Guard 已经发布很久了,很早就想写一篇相关的教程,趁最近一个项目有用到它,正好可以作为一个实例,跟大家展示一下 Guard 的用法。

在 Symfony2 的年代,我就写过一篇文章介绍 Symfony 的用户登录系统。用户登录系统是一个网站开发必须经历,但又不简单的活,从 Symfony 对登录系统的设计就可以看得出来,四个大组件,才能做好用户登录系统。当然 Symfony 开发组也深知原有的设计太『宏大』,估计一开始就会吓跑很多人,所以后来添加了精简版的用户登录系统 Guard。

简而言之,Guard 就是将原本的登录四大组件变成了一个统一的类来处理,从它的接口 GuardAuthenticatorInterface 就能看出来,这里我将按照执行的顺序,依次说明每个接口的意义。

getCredentials(Request $request)

这是每次请求都会执行的方法,让开发者从 $request 对象中获取登录所需要的讯息,比如常见表单登录的用户名和密码,或者微信登录的 code 参数。返回的结果可以是任意的类型,但一般来说用数组形式就够了。如果此方法返回 null,那么 GuardAuthenticatorInterface::start 方法将会被执行;如果不是 null,则 GuardAuthenticatorInterface::getUser 方法将被执行,而 getCredentials 返回的结果将作为 getUser 的第一个参数。

start(Request $request, AuthenticationException $authException = null)

此方法可以理解成传统 Symfony 登录系统的 entry point,即让用户登录的地方。看定义可以发现此方法返回一个 Response,你可以返回带登录表单的页面,或者跳转到微信 OAuth 获取 code 的接口。当用户提交了账号密码,或者微信返回带 code 参数的链接,第二次请求开始,将又从 getCredentials 方法重新开始。

getUser(mixed $credentials, UserProviderInterface $userProvider)

此方法一般来说,都需要利用 UserProviderloadUserByUsername 方法,通过传入 $credentials 里的登录名,或者微信的 openId,返回 User 对象。如果通过用户名找不到对应的 User 对象,既 UserProvider::loadUserByUsername 返回 null,那么 GuardAuthenticatorInterface::onAuthenticationFailure 方法将会被调用;如果 UserProvider::loadUserByUsername 能返回 User 对象,那么 GuardAuthenticatorInterface::checkCredentials 方法将会被调用,而 $user 对象会被作为第二参数被传入,第一参数仍是 $credentials

checkCredentials

此方法将检查用户和 $credentials 是否匹配。比如表单登录,将 $credentials 里的密码信息和 $user 对象里的密码做对比,如果密码不匹配,那么你将在此方法抛出 AuthenticationException 异常或者返回 false 来表示登录失败,从而转向 GuardAuthenticatorInterface::onAuthenticationFailure 方法。

onAuthenticationSuccess

当然,如果 checkCredentials 方法返回 true(即登录成功),那么 GuardAuthenticatorInterface::onAuthenticationSuccess 方法将会被调用,你可以在此方法做一些登录成功之后的事情。此方法需要返回 Response 或者 null,如果返回 null 将继续执行当前路径应当执行的代码;如果返回 Response,则此 Response 会立马发送。比如如果要求用户登录成功都需要返回到首页,那么你就可以在此返回 new RedirectResponse('/')

onAuthenticationFailure

最后是登录失败的处理。类似于登录成功,此方法需要返回 Response,比如显示登录失败的页面,或者继续显示登录表单让用户登录。

还有两个方法,现在先不说。到此是否觉得 Guard 接口的设计让我们对 Symfony 登录思路的理解更加简洁清晰了呢?

把实例给大家展现出来,自己感受感受,利用微信 OAuth2 接口做微信登录。

首先是用户类。跟之前一样,必须实现 Symfony\Component\Security\Core\User\UserInterface

接下来是 UserProvider

一切准备工作就绪,上 Guard:

最后,配置 services 和 firewall 信息,一切就搞定了

使用 Symfony Guard 做用户登录 by Chris Yue is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.

微信赞赏码

文章不错,我要帮站长分担建站费!
天使投赏人

发表评论

− two = two