簡單說一下個人邏輯,我也不知道我理解sso對不對。php
假如三個站點 a.baidu.com b.baidu.com c.baidu.comjson
a.baidu.com 做爲驗證用戶登陸帳戶。
b和c做爲客戶端(子系統)。緩存
b和c須要登陸的時候跳轉到a,而且攜帶參數source指明登錄後跳轉的連接。安全
a站點就是普通的登錄方式(校驗用戶密碼),校驗成功後作一些處理。須要生成一個ticket,具體怎麼生成均可以,只要安全就能夠了。而後存儲到Cache裏面。這裏有疑問,後面總結。登錄成功後直接跳轉到$url就能夠了。session
private function getTicketUrl($source) { $ticket = md5(time()+key); Cache::put($ticket, $user, 120); $url = $source . '?ticket=' . $ticket; return $url; }
假如說a站帶着ticket跳轉到b站(b.baidu.com?ticket=xxxxxxxxxxxxxxxx
)併發
b站作一個全局的過濾器,接受這個ticket而後請求a站驗證ticket是否爲a生成的。ui
b站過濾器App\Http\Middleware\CasAuthenticate
代碼,這裏判斷是否有ticket併發送請求到a站校驗。若是是登錄的,則拿到用戶UID進行登錄。url
public function handle($request, Closure $next) { $ticket = $request->input('ticket'); if ($ticket) { $result = json_decode('http://a.baidu.com' . '/auth/check-ticket?ticket=' . $ticket), true); if ($result['state'] == "SUCCESS") { $request->session()->flush(); Auth::loginUsingId($result['result']['uid']); return redirect(redirect()->getUrlGenerator()->current()); } } return $next($request); }
邏輯算是完成了,可是有幾個疑問。code
1.我這個實現,我本身都不知道是否是對的,這是我根據原理寫出來的。md5
2.假如b站如今跳轉到c站,因爲b站活躍比較頻繁,session一直都在,而a站的緩存時間極有可能已通過期了,此時從b站跳轉到c站,c站跳轉到a站去判斷登錄,結果發現已經失效了,仍是得登錄。因此這是有問題的,因爲咱們業務模塊相關性差,不會隨意跳轉,因此暫不考慮這樣的問題。但這確實是個人一個問題。我沒想清楚。
轉載註明:羅志強的博客