成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

理解JWT(JSON Web Token)認(rèn)證及python實(shí)踐

BigTomato / 1059人閱讀

摘要:認(rèn)證服務(wù)器,即服務(wù)提供商專門(mén)用來(lái)處理認(rèn)證的服務(wù)器。它與認(rèn)證服務(wù)器,可以是同一臺(tái)服務(wù)器,也可以是不同的服務(wù)器。客戶端使用上一步獲得的授權(quán),向認(rèn)證服務(wù)器申請(qǐng)令牌。認(rèn)證服務(wù)器對(duì)客戶端進(jìn)行認(rèn)證以后,確認(rèn)無(wú)誤,同意發(fā)放令牌。

最近想做個(gè)小程序,需要用到授權(quán)認(rèn)證流程。以前項(xiàng)目都是用的 OAuth2 認(rèn)證,但是Sanic 使用OAuth2 不太方便,就想試一下 JWT 的認(rèn)證方式。
這一篇主要內(nèi)容是 JWT 的認(rèn)證原理,以及python 使用 jwt 認(rèn)識(shí)的實(shí)踐。

幾種常用的認(rèn)證機(jī)制 HTTP Basic Auth

HTTP Basic Auth 在HTTP中,基本認(rèn)證是一種用來(lái)允許Web瀏覽器或其他客戶端程序在請(qǐng)求時(shí)提供用戶名和口令形式的身份憑證的一種登錄驗(yàn)證方式,通常用戶名和明碼會(huì)通過(guò)HTTP頭傳遞。

在發(fā)送之前是以用戶名追加一個(gè)冒號(hào)然后串接上口令,并將得出的結(jié)果字符串再用Base64算法編碼。例如,提供的用戶名是Aladdin、口令是open sesame,則拼接后的結(jié)果就是Aladdin:open sesame,然后再將其用Base64編碼,得到QWxhZGRpbjpvcGVuIHNlc2FtZQ==。最終將Base64編碼的字符串發(fā)送出去,由接收者解碼得到一個(gè)由冒號(hào)分隔的用戶名和口令的字符串。

優(yōu)點(diǎn)

基本認(rèn)證的一個(gè)優(yōu)點(diǎn)是基本上所有流行的網(wǎng)頁(yè)瀏覽器都支持基本認(rèn)證。

缺點(diǎn)

由于用戶名和密碼都是Base64編碼的,而B(niǎo)ase64編碼是可逆的,所以用戶名和密碼可以認(rèn)為是明文。所以只有在客戶端和服務(wù)器主機(jī)之間的連接是安全可信的前提下才可以使用。

接下來(lái)我們看一個(gè)更加安全也適用范圍更大的認(rèn)證方式 OAuth。

OAuth

OAuth 是一個(gè)關(guān)于授權(quán)(authorization)的開(kāi)放網(wǎng)絡(luò)標(biāo)準(zhǔn)。允許用戶提供一個(gè)令牌,而不是用戶名和密碼來(lái)訪問(wèn)他們存放在特定服務(wù)提供者的數(shù)據(jù)。現(xiàn)在的版本是2.0版。

嚴(yán)格來(lái)說(shuō),OAuth2不是一個(gè)標(biāo)準(zhǔn)協(xié)議,而是一個(gè)安全的授權(quán)框架。它詳細(xì)描述了系統(tǒng)中不同角色、用戶、服務(wù)前端應(yīng)用(比如API),以及客戶端(比如網(wǎng)站或移動(dòng)App)之間怎么實(shí)現(xiàn)相互認(rèn)證。

名詞定義

Third-party application: 第三方應(yīng)用程序,又稱"客戶端"(client)

HTTP service:HTTP服務(wù)提供商

Resource Owner:資源所有者,通常稱"用戶"(user)。

User Agent:用戶代理,比如瀏覽器。

Authorization server:認(rèn)證服務(wù)器,即服務(wù)提供商專門(mén)用來(lái)處理認(rèn)證的服務(wù)器。

Resource server:資源服務(wù)器,即服務(wù)提供商存放用戶生成的資源的服務(wù)器。它與認(rèn)證服務(wù)器,可以是同一臺(tái)服務(wù)器,也可以是不同的服務(wù)器。

OAuth 2.0 運(yùn)行流程如圖:

(A)用戶打開(kāi)客戶端以后,客戶端要求用戶給予授權(quán)。
(B)用戶同意給予客戶端授權(quán)。
(C)客戶端使用上一步獲得的授權(quán),向認(rèn)證服務(wù)器申請(qǐng)令牌。
(D)認(rèn)證服務(wù)器對(duì)客戶端進(jìn)行認(rèn)證以后,確認(rèn)無(wú)誤,同意發(fā)放令牌。
(E)客戶端使用令牌,向資源服務(wù)器申請(qǐng)獲取資源。
(F)資源服務(wù)器確認(rèn)令牌無(wú)誤,同意向客戶端開(kāi)放資源。

優(yōu)點(diǎn)

快速開(kāi)發(fā)
實(shí)施代碼量小
維護(hù)工作減少
如果設(shè)計(jì)的API要被不同的App使用,并且每個(gè)App使用的方式也不一樣,使用OAuth2是個(gè)不錯(cuò)的選擇。

缺點(diǎn)
OAuth2是一個(gè)安全框架,描述了在各種不同場(chǎng)景下,多個(gè)應(yīng)用之間的授權(quán)問(wèn)題。有海量的資料需要學(xué)習(xí),要完全理解需要花費(fèi)大量時(shí)間。
OAuth2不是一個(gè)嚴(yán)格的標(biāo)準(zhǔn)協(xié)議,因此在實(shí)施過(guò)程中更容易出錯(cuò)。

了解了以上兩種方式后,現(xiàn)在終于到了本篇的重點(diǎn),JWT 認(rèn)證。

JWT 認(rèn)證

Json web token (JWT), 根據(jù)官網(wǎng)的定義,是為了在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于JSON的開(kāi)放標(biāo)準(zhǔn)((RFC 7519).該token被設(shè)計(jì)為緊湊且安全的,特別適用于分布式站點(diǎn)的單點(diǎn)登錄(SSO)場(chǎng)景。JWT的聲明一般被用來(lái)在身份提供者和服務(wù)提供者間傳遞被認(rèn)證的用戶身份信息,以便于從資源服務(wù)器獲取資源,也可以增加一些額外的其它業(yè)務(wù)邏輯所必須的聲明信息,該token也可直接被用于認(rèn)證,也可被加密。

JWT 特點(diǎn)

體積小,因而傳輸速度快

傳輸方式多樣,可以通過(guò)URL/POST參數(shù)/HTTP頭部等方式傳輸

嚴(yán)格的結(jié)構(gòu)化。它自身(在 payload 中)就包含了所有與用戶相關(guān)的驗(yàn)證消息,如用戶可訪問(wèn)路由、訪問(wèn)有效期等信息,服務(wù)器無(wú)需再去連接數(shù)據(jù)庫(kù)驗(yàn)證信息的有效性,并且 payload 支持為你的應(yīng)用而定制化。

支持跨域驗(yàn)證,可以應(yīng)用于單點(diǎn)登錄。

JWT原理

JWT是Auth0提出的通過(guò)對(duì)JSON進(jìn)行加密簽名來(lái)實(shí)現(xiàn)授權(quán)驗(yàn)證的方案,編碼之后的JWT看起來(lái)是這樣的一串字符:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ  

. 分為三段,通過(guò)解碼可以得到:

1. 頭部(Header)
// 包括類別(typ)、加密算法(alg);
{
  "alg": "HS256",
  "typ": "JWT"
}

jwt的頭部包含兩部分信息:

聲明類型,這里是jwt

聲明加密的算法 通常直接使用 HMAC SHA256

然后將頭部進(jìn)行base64加密(該加密是可以對(duì)稱解密的),構(gòu)成了第一部分。

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
2. 載荷(payload)

載荷就是存放有效信息的地方。這些有效信息包含三個(gè)部分:

標(biāo)準(zhǔn)中注冊(cè)聲明

公共的聲名

私有的聲明

公共的聲明 :
公共的聲明可以添加任何的信息,一般添加用戶的相關(guān)信息或其他業(yè)務(wù)需要的必要信息.但不建議添加敏感信息,因?yàn)樵摬糠衷诳蛻舳丝山饷堋?/p>

私有的聲明 :
私有聲明是提供者和消費(fèi)者所共同定義的聲明,一般不建議存放敏感信息,因?yàn)閎ase64是對(duì)稱解密的,意味著該部分信息可以歸類為明文信息。

下面是一個(gè)例子:

// 包括需要傳遞的用戶信息;
{ "iss": "Online JWT Builder", 
  "iat": 1416797419, 
  "exp": 1448333419, 
  "aud": "www.gusibi.com", 
  "sub": "uid", 
  "nickname": "goodspeed", 
  "username": "goodspeed", 
  "scopes": [ "admin", "user" ] 
}

iss: 該JWT的簽發(fā)者,是否使用是可選的;

sub: 該JWT所面向的用戶,是否使用是可選的;

aud: 接收該JWT的一方,是否使用是可選的;

exp(expires): 什么時(shí)候過(guò)期,這里是一個(gè)Unix時(shí)間戳,是否使用是可選的;

iat(issued at): 在什么時(shí)候簽發(fā)的(UNIX時(shí)間),是否使用是可選的;

其他還有:

nbf (Not Before):如果當(dāng)前時(shí)間在nbf里的時(shí)間之前,則Token不被接受;一般都會(huì)留一些余地,比如幾分鐘;,是否使用是可選的;

jti: jwt的唯一身份標(biāo)識(shí),主要用來(lái)作為一次性token,從而回避重放攻擊。

將上面的JSON對(duì)象進(jìn)行base64編碼可以得到下面的字符串。這個(gè)字符串我們將它稱作JWT的Payload(載荷)。

eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE0MTY3OTc0MTksImV4cCI6MTQ0ODMzMzQxOSwiYXVkIjoid3d3Lmd1c2liaS5jb20iLCJzdWIiOiIwMTIzNDU2Nzg5Iiwibmlja25hbWUiOiJnb29kc3BlZWQiLCJ1c2VybmFtZSI6Imdvb2RzcGVlZCIsInNjb3BlcyI6WyJhZG1pbiIsInVzZXIiXX0

信息會(huì)暴露:由于這里用的是可逆的base64 編碼,所以第二部分的數(shù)據(jù)實(shí)際上是明文的。我們應(yīng)該避免在這里存放不能公開(kāi)的隱私信息。

3. 簽名(signature)
// 根據(jù)alg算法與私有秘鑰進(jìn)行加密得到的簽名字串;
// 這一段是最重要的敏感信息,只能在服務(wù)端解密;
HMACSHA256(  
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    SECREATE_KEY
)

jwt的第三部分是一個(gè)簽證信息,這個(gè)簽證信息由三部分組成:

header (base64后的)

payload (base64后的)

secret

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

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJKb2huIFd1IEpXVCIsImlhdCI6MTQ0MTU5MzUwMiwiZXhwIjoxNDQxNTk0NzIyLCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJqcm9ja2V0QGV4YW1wbGUuY29tIiwiZnJvbV91c2VyIjoiQiIsInRhcmdldF91c2VyIjoiQSJ9

最后,我們將上面拼接完的字符串用HS256算法進(jìn)行加密。在加密的時(shí)候,我們還需要提供一個(gè)密鑰(secret)。如果我們用 secret 作為密鑰的話,那么就可以得到我們加密后的內(nèi)容:

pq5IDv-yaktw6XEa5GEv07SzS9ehe6AcVSdTj0Ini4o

將這三部分用.連接成一個(gè)完整的字符串,構(gòu)成了最終的jwt:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE0MTY3OTc0MTksImV4cCI6MTQ0ODMzMzQxOSwiYXVkIjoid3d3Lmd1c2liaS5jb20iLCJzdWIiOiIwMTIzNDU2Nzg5Iiwibmlja25hbWUiOiJnb29kc3BlZWQiLCJ1c2VybmFtZSI6Imdvb2RzcGVlZCIsInNjb3BlcyI6WyJhZG1pbiIsInVzZXIiXX0.pq5IDv-yaktw6XEa5GEv07SzS9ehe6AcVSdTj0Ini4o

簽名的目的:簽名實(shí)際上是對(duì)頭部以及載荷內(nèi)容進(jìn)行簽名。所以,如果有人對(duì)頭部以及載荷的內(nèi)容解碼之后進(jìn)行修改,再進(jìn)行編碼的話,那么新的頭部和載荷的簽名和之前的簽名就將是不一樣的。而且,如果不知道服務(wù)器加密的時(shí)候用的密鑰的話,得出來(lái)的簽名也一定會(huì)是不一樣的。
這樣就能保證token不會(huì)被篡改。

token 生成好之后,接下來(lái)就可以用token來(lái)和服務(wù)器進(jìn)行通訊了。

下圖是client 使用 JWT 與server 交互過(guò)程:

這里在第三步我們得到 JWT 之后,需要將JWT存放在 client,之后的每次需要認(rèn)證的請(qǐng)求都要把JWT發(fā)送過(guò)來(lái)。(請(qǐng)求時(shí)可以放到 header 的 Authorization )

JWT 使用場(chǎng)景

JWT的主要優(yōu)勢(shì)在于使用無(wú)狀態(tài)、可擴(kuò)展的方式處理應(yīng)用中的用戶會(huì)話。服務(wù)端可以通過(guò)內(nèi)嵌的聲明信息,很容易地獲取用戶的會(huì)話信息,而不需要去訪問(wèn)用戶或會(huì)話的數(shù)據(jù)庫(kù)。在一個(gè)分布式的面向服務(wù)的框架中,這一點(diǎn)非常有用。

但是,如果系統(tǒng)中需要使用黑名單實(shí)現(xiàn)長(zhǎng)期有效的token刷新機(jī)制,這種無(wú)狀態(tài)的優(yōu)勢(shì)就不明顯了。

優(yōu)點(diǎn)

快速開(kāi)發(fā)
不需要cookie
JSON在移動(dòng)端的廣泛應(yīng)用
不依賴于社交登錄
相對(duì)簡(jiǎn)單的概念理解

缺點(diǎn)

Token有長(zhǎng)度限制
Token不能撤銷
需要token有失效時(shí)間限制(exp)

python 使用JWT實(shí)踐

我基本是使用 python 作為服務(wù)端語(yǔ)言,我們可以使用 pyjwt:https://github.com/jpadilla/pyjwt/

使用比較方便,下邊是我在應(yīng)用中使用的例子:

import jwt
import time

# 使用 sanic 作為restful api 框架 
def create_token(request):
    grant_type = request.json.get("grant_type")
    username = request.json["username"]
    password = request.json["password"]
    if grant_type == "password":
        account = verify_password(username, password)
    elif grant_type == "wxapp":
        account = verify_wxapp(username, password)
    if not account:
        return {}
    payload = {
        "iss": "gusibi.com",
         "iat": int(time.time()),
         "exp": int(time.time()) + 86400 * 7,
         "aud": "www.gusibi.com",
         "sub": account["_id"],
         "username": account["username"],
         "scopes": ["open"]
    }
    token = jwt.encode(payload, "secret", algorithm="HS256")
    return True, {"access_token": token, "account_id": account["_id"]}
    

def verify_bearer_token(token):
    #  如果在生成token的時(shí)候使用了aud參數(shù),那么校驗(yàn)的時(shí)候也需要添加此參數(shù)
    payload = jwt.decode(token, "secret", audience="www.gusibi.com", algorithms=["HS256"])
    if payload:
        return True, token
    return False, token

這里,我們可以使用 jwt 直接生成 token,不用手動(dòng)base64加密和拼接。

詳細(xì)代碼可以參考 gusibi/Metis: 一個(gè)測(cè)試類小程序(包含前后端代碼)。

這個(gè)項(xiàng)目中,api 使用 python sanic,文檔使用 swagger-py-codegen 生成,提供 swagger ui。

現(xiàn)在可以使用 swagger ui 來(lái)測(cè)試jwt。

總結(jié)

這一篇主要介紹了 jwt 的原理、驗(yàn)證步驟,最后是使用 pyjwt 包演示 生成token以及校驗(yàn)token的方法。

以上提到的包可以在公號(hào)回復(fù)關(guān)鍵字獲取地址

預(yù)告,下一篇是介紹小程序中使用 JWT 的認(rèn)證流程及實(shí)現(xiàn)。 參考鏈接

HTTP基本認(rèn)證

訪問(wèn)需要HTTP Basic Authentication認(rèn)證的資源的各種語(yǔ)言的實(shí)現(xiàn)

理解OAuth 2.0

OAuth 2和JWT - 如何設(shè)計(jì)安全的API?

Securing RESTful Web Services with OAuth2

Server 端的認(rèn)證——擁抱

JSON Web Token - 在Web應(yīng)用間安全地傳遞信息

八幅漫畫(huà)理解使用JSON Web

基于Token的WEB后臺(tái)認(rèn)證機(jī)制

什么是 JWT -- JSON WEB TOKEN


最后,感謝女朋友支持。

歡迎關(guān)注(April_Louisa) 請(qǐng)我喝芬達(dá)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/40655.html

相關(guān)文章

  • JWT refreshtoken 實(shí)踐

    摘要:詳細(xì)介紹可以查看這篇文章理解認(rèn)證及實(shí)踐特點(diǎn)優(yōu)點(diǎn)體積小,因而傳輸速度快傳輸方式多樣,可以通過(guò)參數(shù)頭部等方式傳輸嚴(yán)格的結(jié)構(gòu)化。 Json web token (JWT), 根據(jù)官網(wǎng)的定義,是為了在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于JSON的開(kāi)放標(biāo)準(zhǔn)((RFC 7519).該token被設(shè)計(jì)為緊湊且安全的,特別適用于分布式站點(diǎn)的單點(diǎn)登錄(SSO)場(chǎng)景。JWT的聲明一般被用來(lái)在身份提供者和...

    cod7ce 評(píng)論0 收藏0
  • 微信小程序開(kāi)發(fā):python+sanic 實(shí)現(xiàn)小程序登錄注冊(cè)

    摘要:參考鏈接微信小程序七日談第五天你可能要在登錄功能上花費(fèi)大力氣理解認(rèn)證及實(shí)踐網(wǎng)站微信登錄實(shí)現(xiàn)最后,感謝女朋友支持。 開(kāi)發(fā)微信小程序時(shí),接入小程序的授權(quán)登錄可以快速實(shí)現(xiàn)用戶注冊(cè)登錄的步驟,是快速建立用戶體系的重要一步。這篇文章將介紹 python + sanic + 微信小程序?qū)崿F(xiàn)用戶快速注冊(cè)登錄全棧方案。 微信小程序登錄時(shí)序圖如下: showImg(https://segmentfaul...

    antz 評(píng)論0 收藏0
  • 微信小程序開(kāi)發(fā):python+sanic 實(shí)現(xiàn)小程序登錄注冊(cè)

    摘要:參考鏈接微信小程序七日談第五天你可能要在登錄功能上花費(fèi)大力氣理解認(rèn)證及實(shí)踐網(wǎng)站微信登錄實(shí)現(xiàn)最后,感謝女朋友支持。 開(kāi)發(fā)微信小程序時(shí),接入小程序的授權(quán)登錄可以快速實(shí)現(xiàn)用戶注冊(cè)登錄的步驟,是快速建立用戶體系的重要一步。這篇文章將介紹 python + sanic + 微信小程序?qū)崿F(xiàn)用戶快速注冊(cè)登錄全棧方案。 微信小程序登錄時(shí)序圖如下: showImg(https://segmentfaul...

    Nino 評(píng)論0 收藏0
  • 編寫(xiě) Node.js Rest API 的 10 個(gè)最佳實(shí)踐

    摘要:要對(duì)進(jìn)行黑盒測(cè)試測(cè)試的最好辦法是對(duì)他們進(jìn)行黑盒測(cè)試,黑盒測(cè)試是一種不關(guān)心應(yīng)用內(nèi)部結(jié)構(gòu)和工作原理的測(cè)試方法,測(cè)試時(shí)系統(tǒng)任何部分都不應(yīng)該被。此外,有了黑盒測(cè)試并不意味著不需要單元測(cè)試,針對(duì)的單元測(cè)試還是需要編寫(xiě)的。 本文首發(fā)于之乎專欄前端周刊,全文共 6953 字,讀完需 8 分鐘,速度需 2 分鐘。翻譯自:RingStack 的文章 https://blog.risingstack.co...

    ermaoL 評(píng)論0 收藏0
  • api權(quán)限管理系統(tǒng)與前后端分離實(shí)踐

    摘要:自己在前后端分離上的實(shí)踐要想實(shí)現(xiàn)完整的前后端分離,安全這塊是繞不開(kāi)的,這個(gè)系統(tǒng)主要功能就是動(dòng)態(tài)管理,這次實(shí)踐包含兩個(gè)模塊基于搭建的權(quán)限管理系統(tǒng)后臺(tái)編寫(xiě)的前端管理。 自己在前后端分離上的實(shí)踐 要想實(shí)現(xiàn)完整的前后端分離,安全這塊是繞不開(kāi)的,這個(gè)系統(tǒng)主要功能就是動(dòng)態(tài)restful api管理,這次實(shí)踐包含兩個(gè)模塊,基于springBoot + shiro搭建的權(quán)限管理系統(tǒng)后臺(tái)bootshir...

    bawn 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<