token

1. 一些概念

  • 單點登錄:html

    • 一套公用的用戶體系,登錄後,可以訪問全部的系統。
    • 這只是一類解決方案的統稱,在具體的實施方面,有兩種策略 SAML,OAuth
  • OpenID:web

    • 好比,容許使用微信/支付寶或者其餘帳號 登錄 其餘網站
    • 只用於身份認證,容許你以同一個帳號在多個網站登錄。
    • 登錄後 ,該站點沒法訪問你在 微信 上的數據。
  • Authentication:身份鑑別,也就是 認證(鑑別是否爲合法用戶)
  • Authorisation:受權(鑑別訪問權限)
  • SMAL 2.0: https://zhuanlan.zhihu.com/p/...
  • OAuth :算法

1. token 的典型流程:

  • 用戶登陸的時候,服務端生成一個token(經過登陸信息作數字簽名,加密以後獲得的字符串)返回給客戶端
  • 客戶端後續的請求都帶上這個token
  • 服務端解析token(作解密和簽名認證,判斷其有效性)獲取用戶信息,並響應用戶的請求。
  • token會有過時時間,客戶端登出的時候也會廢棄token,可是服務端不須要任何操做

2. session 和 token 的區別:

  • session, 要求服務端存儲信息,並根據id可以檢索,而 token 不須要。
  • 服務端 要 經過 token 來解析 用戶身份,也須要定義好相應的協議。
  • session 通常使用cookie 來交互。token,能夠是 cookie,也能夠是 其餘heaser,甚至能夠放在請求的內容中。不使用cookie能夠帶來跨域的便利性
  • 不少狀況下,sessin 和 token 能夠一塊兒使用。
  • token 技術 對應的標準,就是JWT

3.JWT(JSON Web Tokens)

  • 組成:數據庫

    • Header(頭部)(是一個JSON 對象)json

      {
        "alg": "HS256", // 表示簽名的算法,默認是 HMAC     SHA256(寫成 HS256)
        "typ": "JWT"  // 表示Token的類型,JWT 令牌統一寫爲JWT
      }
    • Payload(負載)(也是一個JSON 對象-- 用來存放實際須要傳遞的數據)
    {
      // 7個官方字段
      "iss": "a.com", // issuer:簽發人
      "exp": "1d", // expiration time:(必須設置)
      "sub": "test", // subject: 主題
      "aud": "xxx", // audience: 受衆
      "nbf": "xxx", // Not Before:生效時間
      "iat": "xxx", // Issued At: 簽發時間
      "jti": "1111", // JWT ID:編號
      // 能夠定義私有字段
      "name": "John Doe",
      "admin": true
    }
    • Signature(簽名)跨域

      • 對前兩部分的簽名,防止數據被篡改。
      • 須要指定一個密鑰(secret)。
      • 採用的公式:安全

        • header 中的簽名算法(base64UrlEncode(header) + '.' + base64UrlEncode(payload), secret)
  • JWT = Base64(Header) + "." + Base64(Payload) + "." + $Signature
  • 特色:服務器

    • JWT 默認是不加密的,任何人均可以讀到,因此不要把祕密信息放在這個部分。
    • 發送 JWT, 要使用 https,不實用HTTPS的時候,JWT裏面不要寫入祕密數據。
    • 在使用過程當中沒法廢除 某個 token,或者更改 token 的權限,也就是一旦簽發就會始終有效。
  • 使用方法:微信

    • 客戶端,獲得 token 後,能夠存儲在 cookie裏,或者localstorage 中
    • 之後的http 請求都要帶着 這個token
    • 發送的時候:能夠放在cookie 中,也能夠放在 HTTP 請求頭 信息 Authorization 字段中,還能夠在 post 請求的時候放在請求數據體裏。
  • 分類:cookie

    • access token:

      • 有效期短
      • 以上的都是針對 該種 token
    • refresh token:

      • 有效期長。
      • 自身以及過時時間是 存儲在服務器的數據庫中的。
      • 只有在申請新的 access token 的之後纔會驗證,不會對業務接口響應時間形成影響,也不會一直保存在內存中以應對大量的請求。
  • 爲何要有 refresh token?

    • 目的:職能分離。refresh token 負責身份認證,access token 負責請求資源。
  • 流程:

    • client -> server: username && password
    • server: 獲得token
    • server -> client: access token 、 refresh token
    • client:將 token保存在本地
    • client -> server: access token
    • server: access token 沒有過時
    • server -> client: 返回數據
    • client -> server: access token
    • server: access token 過時
    • server -> client: 返回錯誤
    • client -> server: refresh token
    • server: 判斷 refresh token 是否過時
    • server -> client: 沒過時,則返回新 的 access token和 refresh token。若是過時了,須要從新登錄

4. token 和 session 的區別:

  • session:

    • 爲無狀態的HTTP提供持久機制。
    • 若是須要實現有狀態的會話,能夠增長Session來在服務端保存一些狀態。
    • 只提供一種簡單的認證,數據只保存在站點,不該該共享給其餘網站或者第三方APP
  • token:

    • 就是一個令牌。
    • 做爲身份認證安全性更好。
    • 若是你的用戶數據可能須要和第三方共享,或者容許第三方調用API接口,用Token。

5. bearer token:

  • 定義:

    • 用於 OAuth 2.0 受權訪問資源
    • 任何 持有 bearer 的均可以訪問資源,而無需證實持有加密 key。
    • 一個 bearer 表明受權範圍、有效期,以及其餘受權事項。
    • 傳輸時,要防止泄露。
    • 有效期不能過長,過時後,可以使用 refresh token 申請 更新。
  • 資源請求:

    • bearer 實現資源請求移動有 3種方式,如下的優先級依次遞減。
    • Authorization Header: Authorization: Bearer mF_9.B5f-4.1JqM
    • Form-Encoded Body Parameter:

      • 使用:
      Content-Type: application/x-www-form-urlencoded
      
      access_token=mF_9.B5f-4.1JqM
      • 使用條件:

        • 頭部必須包含"Content-Type: application/x-www-form-urlencoded"
        • entity-body必須遵循application/x-www-form-urlencoded編碼(RFC 6749)
        • 若是entity-body除了access_token以外,還包含其餘參數,須以"&"分隔開
        • entity-body只包含ASCII字符
        • 要使用request-body已經定義的請求方法,不能使用GET
    • URI Query Parameter:

      GET /resource?access_token=mF_9.B5f-4.1JqM HTTP/1.1
          Cache-Control: no-store
      • 服務端應在響應中使用 Cache-Control: private
  • WWW-Authenticate 頭:

    • 在客戶端未發送有效Bearer的狀況下,即錯誤發生時,資源服務器鬚髮送WWW-Authenticate頭
    • 例: WWW-Authenticate: Bearer realm="example", error="invalid_token", error_description="The access token expired"
    • 字段用法:

      • Bearer:Beare做爲一種認證類型(基於OAuth 2.0),使用"Bearer"關鍵詞進行定義
      • realm:與Basic、Digest同樣,Bearer也使用相同含義的域定義reaml
      • scope:受權範圍,可選的,大小寫敏感的,空格分隔的列表(%x21 / %x23-5B / %x5D-7E),能夠是受權服務器定義的任何值,不該展現給終端用戶。OAuth 2.0還規定客戶端發送scope請求參數以指定受權訪問範圍,而在實際受權範圍與客戶端請求受權範圍不一致時,受權服務器可發送scope響應參數以告知客戶端下發的token實際的受權範圍。下爲兩個scope用法實例:
    scope="urn:example:channel=HBO&urn:example:rating=G,PG-13"```
    - error:描述訪問請求被拒絕的緣由,字符%x20-21 / %x23-5B / %x5D-7E以內
    - error_description:向開發者提供一個可讀的解釋,字符%x20-21 / %x23-5B / %x5D-7E以內
    - error_uri:absolute URI,標識人工可讀解釋錯誤的頁面,字符%x21 / %x23-5B / %x5D-7E以內.當錯誤發生時,資源服務器將發送的HTTP Status Code(一般是400, 401, 403, 或405)及Error Code以下:
    - invalid_request:請求丟失參數,或包含無效參數、值,參數重複,多種方法發送access token,畸形等。資源服務器將發送HTTP 400 (Bad Request)
    - invalid_token:access token過時、廢除、畸形,或存在其餘無效理由的狀況。資源服務器將發送HTTP 401 (Unauthorized),而客戶端則須要申請一個新的access token,而後才能從新發送該資源請求
  • bearer token response:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
   "access_token":"mF_9.B5f-4.1JqM",
   "token_type":"Bearer",
   "expires_in":3600,
   "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA"
}
```
  • 安全威脅:

    • token 僞造/修改: 攻擊者僞造/修改 已有的 token,致使資源服務器受權 經過非法訪問的客戶端,所以須要對 token 使用數字簽名或者消息認證碼來保證完整性。
    • token 泄漏:自己包含認證、有效期等敏感信息,因此須要加密。
    • token 改寄:攻擊者用一個訪問A資源服務器的token去請求B資源服務器的資源。所以一般 token 中能夠包含表明資源服務器的標識 來防止這種狀況的發生。
    • token 重放:攻擊者企圖使用曾經使用過的token來請求資源。所以token需包含有效期(好比少於1小時)

5. 參考:

相關文章
相關標籤/搜索