javascript
jwt如何防止token被窃取_在吗?认识一下JWT(JSON Web Token)?
什么是JSON Web Token ?
官網介紹:
JSON Web Token(JWT)是一個開放標準(RFC 7519),它定義了一種緊湊且自包含的方式,用于在各方之間安全地將信息作為JSON對象傳輸。由于此信息是經過數字簽名的,因此可以被驗證和信任。可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公用/專用密鑰對對JWT進行簽名。
盡管可以對JWT進行加密以在各方之間提供保密性,但我們將重點關注已簽名的令牌。簽名的令牌可以驗證其中包含的聲明的完整性,而加密的令牌則將這些聲明隱藏在其他方的面前。當使用公鑰/私鑰對對令牌進行簽名時,簽名還證明只有持有私鑰的一方才是對其進行簽名的一方。
emmmm.......balabala一堆文字,那么我們來簡單總結下:
JWT是一個JSON信息傳輸的開放標準,它可以使用密鑰對信息進行數字簽名,以確保信息是可驗證和可信任的。
JWT的結構是什么?
JWT由三部分構成:header(頭部)、payload(載荷)和signature(簽名)。 以緊湊的形式由這三部分組成,由“.“分隔。
因此,JWT通常如下所示。
xxxxx.yyyyy.zzzzz
讓我們把這串奇奇怪怪的東西分解開來:
header
header通常由兩部分組成:令牌的類型(即JWT)和所使用的簽名算法,例如HMAC SHA256或RSA等等。
例如:
{ ?"alg": "HS256", "typ": "JWT" }顯而易見,這貨是一個json數據,然后這貨會被Base64編碼形成JWT的第一部分,也就是xxxxx.yyyyy.zzzzz中的xxxxxx。
Payload
這貨是JWT的第二部分,叫載荷(負載),內容也是一個json對象,它是存放有效信息的地方,它可以存放JWT提供的現成字段 :
- iss: 該JWT的簽發者。
- sub: 該JWT所面向的用戶。
- aud: 接收該JWT的一方。
- exp(expires): 什么時候過期,這里是一個Unix時間戳。
- iat(issued at): 在什么時候簽發的。
舉個例子:
{??"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內容被篡改。將上面的兩個編碼后的字符串都用英文句號.連接在一起(頭部在前),就形成了
xxxxxx.yyyyyy然后再使用header中聲明簽名算法進行簽名。 如果要使用HMAC SHA256算法,則將通過以下方式創建簽名:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)當然,在加密的時候,我們還需要提供一個密鑰(secret),我們可以自己隨意指定。這樣就形成了JWT的第三部分,也就是xxxxx.yyyyy.zzzzz中的zzzzzz。
最后,我們把這三個部分拼在一起,就形成了一個完整的JWT。
下面展示了一個完整的JWT,它先對header和payload進行編碼,最后用一個密鑰形成了簽名。
如果我們想試驗一下的話,可以在JWT的官網進行debugger。貼一下官網: https://jwt.io/
JSON Web Token認證流程
什么時候應該使用JSON Web Token?
以下是JSON Web Token 有用的一些情況:
- 授權:這是使用JWT的最常見方案。一旦用戶登錄,每個后續請求將包括JWT,從而允許用戶訪問該令牌允許的路由,服務和資源。單一登錄是當今廣泛使用JWT的一項功能,因為它的開銷很小并且可以在不同的域中輕松使用。
- 信息交換:JSON Web Token是在各方之間安全地傳輸信息的好方法。因為可以對JWT進行簽名(例如,使用公鑰/私鑰對),所以您可以確定發件人是他們所說的人。此外,由于簽名是使用標頭和有效負載計算的,因此您還可以驗證內容是否遭到篡改。
那么,有人就會說了,道理我都懂,我應該怎樣去實現呢?莫慌。。
如何實現?
接下來我會用python實現JWT,不想拉仇恨,但是,python大法好啊。。。。
在前后端分離的項目中,我們需要與前端約定一種身份認證機制。當用戶登錄的時候,后端會生成token,然后返回給前端,前端需要將token拿到并按照一定規則放到header中,在下一次請求的時候一并發送給后端,后端進行token身份校驗。
這里我們約定前端請求后端服務時需要添加頭信息Authorization ,內容為token。
我用的是fastapi web框架,搭建項目非常快。
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簽名所使用的密鑰,是私密的,只在服務端保存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="認證失敗,無權查看", 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通過,查詢成功"}這里,由于現有的JWT庫已經幫我們封裝好了,我們可以使用JWT直接生成 token,不用手動base64加密和拼接。
測試一下:
啟動項目之后,我們打開http://127.0.0.1:8000/docs# ,就會看到以下我們編寫好的api:
首先,我們先驗證一下create_token接口
當我們輸入用戶名,密碼后,后端進行驗證,驗證成功后會返回給前端一個token,也就是JWT。當前端拿到這個token之后,下次在請求的時候就必須要帶上這個token了,因為前后端已經約定好了。接下來我們試一下:
認證失敗???
什么原因導致的呢??讓我們點開檢查抓一下包看看:
恍然大悟,剛才我們說過,前后端事先約定好的,請求的header中一定要帶上token,在Authorization ,內容token。我們現在這個請求的header中并沒有帶上token,那這種debug模式下又是改不了請求header信息的,我們可以使用接口測試工具進行測試,我主推Postman!!!,讓我們來試一下:
至此,JWT介紹以及使用梳理完畢。
最后,感謝女朋友在生活中,工作上的包容、理解與支持 !
總結
以上是生活随笔為你收集整理的jwt如何防止token被窃取_在吗?认识一下JWT(JSON Web Token)?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《帝国时代4》设计总监离职 在Relic
- 下一篇: spring 单例 获取多例的位_Spr