转自:https://www.jianshu.com/p/ef7b1bce1e1c
前言
Laravel开箱即用的用户登录注册甚是好用,如果你还不知道如何使用请移步用户认证文档。但笔者发现一个问题,remeber_token的问题。remeber_token只要在用户选择了记住密码的按钮,那么只要用户不退出,那么这个token将持续五年,意思就是在五年之内,你都可以拿着这个remeber_token去登录这个账号。显然,这是不安全的。
而参照了大多数网站的做法,应该是每一次登录,即刷新这个token,让一个token的变为一次性的事物。这样能增强登录验证的安全性。
那在laravel中怎么做呢?
笔者翻阅了源码,做了诸多实验之后,终于是做到了。但笔者是修改的源码,如果想要在生产环境中使用,不建议这么做。
本文主要是为了带大家疏通思路,看一下源码。
解决方案
首先查看登录的源码部分,由于多层调用,建议使用IDE快速命中。 登陆的核心逻辑在vendor/laravel/framework/src/Illuminate/Auth/SessionGuard.php之中,其中的functionattempt是其具体的实现逻辑。同文件目录下的functionlogin是在用户比对完成后,添加session的部分,这一个位置比较重要。
然后,查看auth中间件的逻辑。在vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php中,可以看到中间的调用逻辑。
其最终调用的是vendor/laravel/framework/src/Illuminate/Auth/SessionGuard.php的functionuser(),
其中
$recaller = $this->recaller();
remeber_token与现有的数据进行比对,当比对成功返回user的信息,再将其保存在session中。这样就实现了,remeber_token的登录了。
但需要注意的是此时,remeber_token没有变化,这时如果想要做到remeber_token跟随登录后,进行改变的话,那么我们就需要在functionuser()做一点手脚了。
我们可以模仿登录,让remeber_token能够进行改变。那么只需要将login的逻辑拿过来就ok了。
将functionuser改写如下:
...
// If the user is null, but we decrypt a "recaller" cookie we can attempt to
// pull the user data on that cookie which serves as a remember cookie on
// the application. Once we have a user we can return it to the caller.
$recaller = $this->recaller();
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">is_null</span><span class="token punctuation">(</span><span class="token variable">$user</span><span class="token punctuation">)</span> <span class="token operator">&&</span> <span class="token operator">!</span> <span class="token function">is_null</span><span class="token punctuation">(</span><span class="token variable">$recaller</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token variable">$user</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">userFromRecaller</span><span class="token punctuation">(</span><span class="token variable">$recaller</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$user</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// 重新生成token</span>
<span class="token variable">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">cycleRememberToken</span><span class="token punctuation">(</span><span class="token variable">$user</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 重新定义用户</span>
<span class="token variable">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">setUser</span><span class="token punctuation">(</span><span class="token variable">$user</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 刷新cookie</span>
<span class="token variable">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">queueRecallerCookie</span><span class="token punctuation">(</span><span class="token variable">$user</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 更新session</span>
<span class="token variable">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">updateSession</span><span class="token punctuation">(</span><span class="token variable">$user</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">getAuthIdentifier</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 退出登录事件</span>
<span class="token variable">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">fireLoginEvent</span><span class="token punctuation">(</span><span class="token variable">$user</span><span class="token punctuation">,</span> <span class="token boolean constant">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token variable">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">user</span> <span class="token operator">=</span> <span class="token variable">$user</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
因为是修改的源码,显然这时不可取的。笔者已向taylor大神发送了邮件,表达了这个看法,如果taylor大神认可的的话,可能再接下来的版本中就能够看到这一项更新了。
当然,如果你现在就要使用的话,不建议修改源码。建议自己写一个记住密码的功能。
评论 (0)