1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        工作3年,還不懂單點登錄系統(tǒng)?看看這8幅漫畫~

        共 4412字,需瀏覽 9分鐘

         ·

        2021-11-29 21:26

        相關閱讀

        300本計算機編程的經(jīng)典書籍下載

        AI全套:Python3+TensorFlow打造人臉識別智能小程序

        最新人工智能資料-Google工程師親授 Tensorflow-入門到進階

        Java架構全階段七期完整

        黑馬頭條項目 - Java Springboot2.0(視頻、資料、代碼和講義)14天完整版

        Spring核心編程思想


        來源:blog.leapoahead.com/2015/09/07/user-authentication-with-jwt/

        我嘗試用八幅漫畫先讓大家理解如何設計正常的用戶認證系統(tǒng),然后再延伸到單點登錄系統(tǒng)。


        JWT 簡介


        JSON Web Token(JWT)是一個非常輕巧的規(guī)范。這個規(guī)范允許我們使用JWT在用戶和服務器之間傳遞安全可靠的信息。


        讓我們來假想一下一個場景。在A用戶關注了B用戶的時候,系統(tǒng)發(fā)郵件給B用戶,并且附有一個鏈接“點此關注A用戶”。鏈接的地址可以是這樣的
        https://your.awesome-app.com/make-friend/?from_user=B&target_user=A

        上面的URL主要通過URL來描述這個當然這樣做有一個弊端,那就是要求用戶B用戶是一定要先登錄的??刹豢梢院喕@個流程,讓B用戶不用登錄就可以完成這個操作。JWT就允許我們做到這點。



        JWT 的組成


        一個JWT實際上就是一個字符串,它由三部分組成:頭部、載荷與簽名。


        載荷(Payload)
        我們先將上面的添加好友的操作描述成一個JSON對象。其中添加了一些其他的信息,幫助今后收到這個JWT的服務器理解這個JWT。
        { "iss": "John Wu JWT", "iat": 1441593502, "exp": 1441594722, "aud": "www.example.com", "sub": "[email protected]", "from_user": "B", "target_user": "A"}

        這里面的前五個字段都是由JWT的標準所定義的。


        這些定義都可以在標準中找到。


        將上面的JSON對象進行[base64編碼]可以得到下面的字符串。這個字符串我們將它稱作JWT的Payload(載荷)。搜索公眾號互聯(lián)網(wǎng)架構師回復“2T”,送你一份驚喜禮包。

        eyJpc3MiOiJKb2huIFd1IEpXVCIsImlhdCI6MTQ0MTU5MzUwMiwiZXhwIjoxNDQxNTk0NzIyLCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJqcm9ja2V0QGV4YW1wbGUuY29tIiwiZnJvbV91c2VyIjoiQiIsInRhcmdldF91c2VyIjoiQSJ9

        如果你使用Node.js,可以用Node.js的包base64url來得到這個字符串。
        var base64url = require('base64url')var header = {    "from_user": "B",    "target_user": "A"}console.log(base64url(JSON.stringify(header)))//?輸出:eyJpc3MiOiJKb2huIFd1IEpXVCIsImlhdCI6MTQ0MTU5MzUwMiwiZXhwIjoxNDQxNTk0NzIyLCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJqcm9ja2V0QGV4YW1wbGUuY29tIiwiZnJvbV91c2VyIjoiQiIsInRhcmdldF91c2VyIjoiQSJ9

        頭部(Header)
        JWT還需要一個頭部,頭部用于描述關于該JWT的最基本的信息,例如其類型以及簽名所用的算法等。這也可以被表示成一個JSON對象。
        {  "typ": "JWT",  "alg": "HS256"}

        在這里,我們說明了這是一個JWT,并且我們所用的簽名算法(后面會提到)是HS256算法。


        對它也要進行Base64編碼,之后的字符串就成了JWT的Header(頭部)。
        eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

        簽名(簽名)

        將上面的兩個編碼后的字符串都用句號.連接在一起(頭部在前),就形成了

        eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0

        這一部分的過程在node-jws的源碼中有體現(xiàn)

        最后,我們將上面拼接完的字符串用HS256算法進行加密。在加密的時候,我們還需要提供一個密鑰(secret)。如果我們用mystar作為密鑰的話,那么就可以得到我們加密后的內容搜索公眾號互聯(lián)網(wǎng)架構師回復“2T”,送你一份驚喜禮包。
        rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM

        這一部分又叫做簽名。


        最后將這一部分簽名也拼接在被簽名的字符串后面,我們就得到了完整的JWT

        eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0.rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM

        于是,我們就可以將郵件中的URL改成

        https://your.awesome-app.com/make-friend/?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0.rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM

        這樣就可以安全地完成添加好友的操作了!

        用戶認證八步走


        所謂用戶認證(Authentication),就是讓用戶登錄,并且在接下來的一段時間內讓用戶訪問網(wǎng)站時可以使用其賬戶,而不需要再次登錄的機制。

        小知識:可別把用戶認證和用戶授權(Authorization)搞混了。用戶授權指的是規(guī)定并允許用戶使用自己的權限,例如發(fā)布帖子、管理站點等。

        首先,服務器應用(下面簡稱“應用”)讓用戶通過Web表單將自己的用戶名和密碼發(fā)送到服務器的接口。這一過程一般是一個HTTP POST請求。建議的方式是通過SSL加密的傳輸(https協(xié)議),從而避免敏感信息被嗅探。


        接下來,應用和數(shù)據(jù)庫核對用戶名和密碼。


        核對用戶名和密碼成功后,應用將用戶的id(圖中的user_id)作為JWT Payload的一個屬性,將其與頭部分別進行Base64編碼拼接后簽名,形成一個JWT。這里的JWT就是一個形同lll.zzz.xxx的字符串。


        應用將JWT字符串作為該請求Cookie的一部分返回給用戶。注意,在這里必須使用HttpOnly屬性來防止Cookie被JavaScript讀取,從而避免跨站腳本攻擊(XSS攻擊)。


        在Cookie失效或者被刪除前,用戶每次訪問應用,應用都會接受到含有jwt的Cookie。從而應用就可以將JWT從請求中提取出來。


        應用通過一系列任務檢查JWT的有效性。例如,檢查簽名是否正確;檢查Token是否過期;檢查Token的接收方是否是自己(可選)。


        應用在確認JWT有效之后,JWT進行Base64解碼(可能在上一步中已經(jīng)完成),然后在Payload中讀取用戶的id值,也就是user_id屬性。這里用戶的id為1025。


        應用從數(shù)據(jù)庫取到id為1025的用戶的信息,加載到內存中,進行ORM之類的一系列底層邏輯初始化。


        應用根據(jù)用戶請求進行響應。
        ? ?


        單點登錄


        Session方式來存儲用戶id,一開始用戶的Session只會存儲在一臺服務器上。對于有多個子域名的站點,每個子域名至少會對應一臺不同的服務器,例如:

        www.taobao.comnv.taobao.comnz.taobao.comlogin.taobao.com

        所以如果要實現(xiàn)在login.taobao.com登錄后,在其他的子域名下依然可以取到Session,這要求我們在多臺服務器上同步Session。


        使用JWT的方式則沒有這個問題的存在,因為用戶的狀態(tài)已經(jīng)被傳送到了客戶端。因此,我們只需要將含有JWT的Cookie的domain設置為頂級域名即可,例如
        Set-Cookie: jwt=lll.zzz.xxx; HttpOnly; max-age=980000; domain=.taobao.com

        注意domain必須設置為一個點加頂級域名,即.taobao.com。這樣,taobao.com和*.taobao.com就都可以接受到這個Cookie,并獲取JWT了。





        全棧架構社區(qū)交流群

        ?「全棧架構社區(qū)」建立了讀者架構師交流群,大家可以添加小編微信進行加群。歡迎有想法、樂于分享的朋友們一起交流學習。

        掃描添加好友邀你進架構師群,加我時注明姓名+公司+職位】

        看完本文有收獲?請轉發(fā)分享給更多人


        往期資源:


        Flutter 移動應用開發(fā)實戰(zhàn) 視頻(開發(fā)你自己的抖音APP)
        Java面試進階訓練營 第2季(分布式篇)
        Java高級 - 分布式系統(tǒng)開發(fā)技術視頻
        瀏覽 110
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产又大又长又粗视频在线 | 在线亚洲自拍 | 亚洲网站在线观看视频 | 黄色小说集| h双腿涨灌触手play慎入视频 | 中日韩欧美风情视频 | 一区二区三区四区精品视频 | 丁香五月婷婷色爱 | 成人性生交片无码视频 | 大鸡巴插嫩逼 |