javascript
jwt如何防止token被窃取_在吗?认识一下JWT(JSON Web Token)?
什么是JSON Web Token ?
官網(wǎng)介紹:
JSON Web Token(JWT)是一個開放標(biāo)準(zhǔn)(RFC 7519),它定義了一種緊湊且自包含的方式,用于在各方之間安全地將信息作為JSON對象傳輸。由于此信息是經(jīng)過數(shù)字簽名的,因此可以被驗證和信任??梢允褂妹孛?使用HMAC算法)或使用RSA或ECDSA的公用/專用密鑰對對JWT進(jìn)行簽名。
盡管可以對JWT進(jìn)行加密以在各方之間提供保密性,但我們將重點關(guān)注已簽名的令牌。簽名的令牌可以驗證其中包含的聲明的完整性,而加密的令牌則將這些聲明隱藏在其他方的面前。當(dāng)使用公鑰/私鑰對對令牌進(jìn)行簽名時,簽名還證明只有持有私鑰的一方才是對其進(jìn)行簽名的一方。
emmmm.......balabala一堆文字,那么我們來簡單總結(jié)下:
JWT是一個JSON信息傳輸?shù)拈_放標(biāo)準(zhǔn),它可以使用密鑰對信息進(jìn)行數(shù)字簽名,以確保信息是可驗證和可信任的。
JWT的結(jié)構(gòu)是什么?
JWT由三部分構(gòu)成:header(頭部)、payload(載荷)和signature(簽名)。 以緊湊的形式由這三部分組成,由“.“分隔。
因此,JWT通常如下所示。
xxxxx.yyyyy.zzzzz
讓我們把這串奇奇怪怪的東西分解開來:
header
header通常由兩部分組成:令牌的類型(即JWT)和所使用的簽名算法,例如HMAC SHA256或RSA等等。
例如:
{ ?"alg": "HS256", "typ": "JWT" }顯而易見,這貨是一個json數(shù)據(jù),然后這貨會被Base64編碼形成JWT的第一部分,也就是xxxxx.yyyyy.zzzzz中的xxxxxx。
Payload
這貨是JWT的第二部分,叫載荷(負(fù)載),內(nèi)容也是一個json對象,它是存放有效信息的地方,它可以存放JWT提供的現(xiàn)成字段 :
- iss: 該JWT的簽發(fā)者。
- sub: 該JWT所面向的用戶。
- aud: 接收該JWT的一方。
- exp(expires): 什么時候過期,這里是一個Unix時間戳。
- iat(issued at): 在什么時候簽發(fā)的。
舉個例子:
{??"iss": "www.baidu.com", "sub": "you",??"aud": "me", "name": "456", "admin": true,? "iat": 1584091337,? "exp": 1784091337,}這貨同樣會被Base64編碼,然后形成JWT的第二部分,也就是xxxxx.yyyyy.zzzzz中的yyyyyy。
Signature
這是JWT的第三部分,叫做簽名,此部分用于防止JWT內(nèi)容被篡改。將上面的兩個編碼后的字符串都用英文句號.連接在一起(頭部在前),就形成了
xxxxxx.yyyyyy然后再使用header中聲明簽名算法進(jìn)行簽名。 如果要使用HMAC SHA256算法,則將通過以下方式創(chuàng)建簽名:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)當(dāng)然,在加密的時候,我們還需要提供一個密鑰(secret),我們可以自己隨意指定。這樣就形成了JWT的第三部分,也就是xxxxx.yyyyy.zzzzz中的zzzzzz。
最后,我們把這三個部分拼在一起,就形成了一個完整的JWT。
下面展示了一個完整的JWT,它先對header和payload進(jìn)行編碼,最后用一個密鑰形成了簽名。
如果我們想試驗一下的話,可以在JWT的官網(wǎng)進(jìn)行debugger。貼一下官網(wǎng): https://jwt.io/
JSON Web Token認(rèn)證流程
什么時候應(yīng)該使用JSON Web Token?
以下是JSON Web Token 有用的一些情況:
- 授權(quán):這是使用JWT的最常見方案。一旦用戶登錄,每個后續(xù)請求將包括JWT,從而允許用戶訪問該令牌允許的路由,服務(wù)和資源。單一登錄是當(dāng)今廣泛使用JWT的一項功能,因為它的開銷很小并且可以在不同的域中輕松使用。
- 信息交換:JSON Web Token是在各方之間安全地傳輸信息的好方法。因為可以對JWT進(jìn)行簽名(例如,使用公鑰/私鑰對),所以您可以確定發(fā)件人是他們所說的人。此外,由于簽名是使用標(biāo)頭和有效負(fù)載計算的,因此您還可以驗證內(nèi)容是否遭到篡改。
那么,有人就會說了,道理我都懂,我應(yīng)該怎樣去實現(xiàn)呢?莫慌。。
如何實現(xiàn)?
接下來我會用python實現(xiàn)JWT,不想拉仇恨,但是,python大法好啊。。。。
在前后端分離的項目中,我們需要與前端約定一種身份認(rèn)證機制。當(dāng)用戶登錄的時候,后端會生成token,然后返回給前端,前端需要將token拿到并按照一定規(guī)則放到header中,在下一次請求的時候一并發(fā)送給后端,后端進(jìn)行token身份校驗。
這里我們約定前端請求后端服務(wù)時需要添加頭信息Authorization ,內(nèi)容為token。
我用的是fastapi web框架,搭建項目非??臁?/p>from datetime import timedelta, datetimeimport jwtfrom fastapi import FastAPI, HTTPException, Dependsfrom starlette.status import HTTP_401_UNAUTHORIZEDfrom starlette.requests import Requestapp = FastAPI()SECRET_KEY = "sdifhgsiasfjaofhslio" # JWY簽名所使用的密鑰,是私密的,只在服務(wù)端保存ALGORITHM = "HS256" # 加密算法,我這里使用的是HS256@app.get("/")async def root(): return {"message": "Hello World"}@app.post("/create_token")def create_token(username,password): if username == "123" and password == "123": access_token_expires = timedelta(minutes=60) expire = datetime.utcnow() + access_token_expires payload = { "sub": username, "exp": expire } # 生成Token,返回給前端 access_token = jwt.encode(payload, SECRET_KEY, algorithm=ALGORITHM) return {"access_token": access_token, "token_type": "bearer"} else: raise HTTPException( status_code=HTTP_401_UNAUTHORIZED, detail="username or password are not true", headers={"WWW-Authenticate": "Bearer"} )def authorized_user(token): try: payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) username: str = payload.get("sub") print(username) if username == "123": return username except jwt.PyJWTError: raise HTTPException( status_code=HTTP_401_UNAUTHORIZED, detail="認(rèn)證失敗,無權(quán)查看", headers={"WWW-Authenticate": "Bearer"},)@app.get("/app")def create_token(request: Request): print(request.headers.get("host"), request.headers.get("Authorization")) user = authorized_user(request.headers.get("Authorization")) # 驗證Token if user: return {"username": user,"detail": "JWT通過,查詢成功"}
這里,由于現(xiàn)有的JWT庫已經(jīng)幫我們封裝好了,我們可以使用JWT直接生成 token,不用手動base64加密和拼接。
測試一下:
啟動項目之后,我們打開http://127.0.0.1:8000/docs# ,就會看到以下我們編寫好的api:
首先,我們先驗證一下create_token接口
當(dāng)我們輸入用戶名,密碼后,后端進(jìn)行驗證,驗證成功后會返回給前端一個token,也就是JWT。當(dāng)前端拿到這個token之后,下次在請求的時候就必須要帶上這個token了,因為前后端已經(jīng)約定好了。接下來我們試一下:
認(rèn)證失敗???
什么原因?qū)е碌哪?#xff1f;?讓我們點開檢查抓一下包看看:
恍然大悟,剛才我們說過,前后端事先約定好的,請求的header中一定要帶上token,在Authorization ,內(nèi)容token。我們現(xiàn)在這個請求的header中并沒有帶上token,那這種debug模式下又是改不了請求header信息的,我們可以使用接口測試工具進(jìn)行測試,我主推Postman!!!,讓我們來試一下:
至此,JWT介紹以及使用梳理完畢。
最后,感謝女朋友在生活中,工作上的包容、理解與支持 !
總結(jié)
以上是生活随笔為你收集整理的jwt如何防止token被窃取_在吗?认识一下JWT(JSON Web Token)?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《帝国时代4》设计总监离职 在Relic
- 下一篇: 世界首富有多壕?马斯克今年纳税超110亿