sso單點登錄的PHP實現(Laravel框架)


簡單說一下我的邏輯,我也不知道我理解sso對不對。

假如三個站點 a.baidu.com b.baidu.com c.baidu.com

a.baidu.com 作為驗證用戶登錄賬戶。
b和c作為客戶端(子系統)。

b和c需要登錄的時候跳轉到a,並且攜帶參數source指明登陸后跳轉的鏈接。

a站點就是普通的登陸方式(校驗用戶密碼),校驗成功后做一些處理。需要生成一個ticket,具體怎么生成都可以,只要安全就可以了。然后存儲到Cache里面。這里有疑問,后面總結。登陸成功后直接跳轉到$url就可以了。

    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生成的。

b站過濾器App\Http\Middleware\CasAuthenticate代碼,這里判斷是否有ticket並發送請求到a站校驗。如果是登陸的,則拿到用戶UID進行登陸。

    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);
    }

邏輯算是完成了,但是有幾個疑問。

1.我這個實現,我自己都不知道是不是對的,這是我根據原理寫出來的。

2.假如b站現在跳轉到c站,由於b站活躍比較頻繁,session一直都在,而a站的緩存時間極有可能已經過期了,此時從b站跳轉到c站,c站跳轉到a站去判斷登陸,結果發現已經失效了,還是得登陸。所以這是有問題的,由於我們業務模塊相關性差,不會隨意跳轉,所以暫不考慮這樣的問題。但這確實是我的一個問題。我沒想清楚。

轉載注明:羅志強的博客


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM