前言
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();
的邏輯,是使用request中的cookieremeber_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();
if (is_null($user) && ! is_null($recaller)) {
$user = $this->userFromRecaller($recaller);
if ($user) {
// 重新生成token
$this->cycleRememberToken($user);
// 重新定義用戶
$this->setUser($user);
// 刷新cookie
$this->queueRecallerCookie($user);
// 更新session
$this->updateSession($user->getAuthIdentifier());
// 退出登錄事件
$this->fireLoginEvent($user, true);
}
}
return $this->user = $user;
}
當完成了這一步,你的token就能夠隨著登錄而重新刷新了。
因為是修改的源碼,顯然這時不可取的。筆者已向taylor大神發送了郵件,表達了這個看法,如果taylor大神認可的的話,可能再接下來的版本中就能夠看到這一項更新了。
當然,如果你現在就要使用的話,不建議修改源碼。建議自己寫一個記住密碼的功能。