網站首頁 編程語言 正文
前言
最近寫的項目中用到了JWT
鑒權,因此做個記錄
原先的jwt-go
倉庫已經不再維護,遷移到了github.com/golang-jwt/jwt/v4
但是網上大多數還是v3
版本的使用教程,建議使用更加安全的v4
1.什么是JWT
JSON Web Token (JWT)是一個開放標準(RFC 7519),它定義了一種緊湊的、自包含的方式,用于作為JSON對象在各方之間安全地傳輸信息。特別適用于分布式站點的單點登錄(SSO)場景。JWT的聲明一般被用來在身份提供者和服務提供者間傳遞被認證的用戶身份信息,以便于從資源服務器獲取資源,也可以增加一些額外的其它業務邏輯所必須的聲明信息,該token也可直接被用于認證,也可被加密。
2.JWT的數據結構
實際的JWT
由三部分組成,如下圖
中間用點(.
)分隔成三個部分。注意,JWT
內部是沒有換行的,這里只是為了便于展示,將它寫成了幾行。JWT的三個部分依次如下:
-
Header
(頭部) -
Payload
(負載) -
Signature
(簽名)
寫成一行就是Header.Payload.Signature
2.1 Header
Header
部分是一個 JSON
對象,描述 JWT
的元數據,通常是下面的樣子
{ "alg": "HS256", "typ": "JWT" }
上面代碼中,alg
屬性表示簽名的算法(algorithm
),默認是HMAC SHA256
(寫成 HS256
);typ
屬性表示這個令牌(token
)的類型(type
),JWT
令牌統一寫為JWT
。
將上面的 JSON
對象使用 Base64URL
算法(詳見后文)轉成字符串就成了第一部分Header
。
2.2 Payload
Payload
部分也是一個 JSON
對象,用來存放實際需要傳遞的數據。JWT
規定了7個官方字段,供選用。
-
iss (issuer)
:簽發人 -
exp (expiration time)
:過期時間 -
sub (subject)
:主題 -
aud (audience)
:受眾 -
nbf (Not Before)
:生效時間 -
iat (Issued At)
:簽發時間 -
jti (JWT ID)
:編號
我們還可以在這個部分自己定義字段,下面就是一個例子
{ "sub": "1234567890", "name": "John Doe", "admin": true }
注意,JWT
默認是不加密的,任何人都可以讀到,所以不要把秘密信息放在這個部分。
這個 JSON
對象也要使用 Base64URL
算法轉成字符串。
2.3 Signature
Signature
部分是對前兩部分的簽名,防止數據篡改。
首先,需要指定一個密鑰(secret
)。這個密鑰只有服務器才知道,不能泄露給用戶。然后,使用 Header
里面指定的簽名算法(默認是 HMAC SHA256
),按照下面的公式產生簽名。
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
2.4 Base64URL
前面提到,Header
和 Payload
串型化的算法是 Base64URL
。這個算法跟 Base64
算法基本類似,但有一些小的不同。
JWT
作為一個令牌(token
),有些場合可能會放到 URL
(比如 api.example.com/?token=xxx)。Base64
有三個字符+,/和=,在 URL
里面有特殊含義,所以要被替換掉:=被省略、+替換成-,/替換成_ 。這就是 Base64URL
算法。
算出簽名以后,把 Header
、Payload
、Signature
三個部分拼成一個字符串,每個部分之間用"點"(.)分隔,就可以返回給用戶。
3使用JWT
安裝
go install "github.com/golang-jwt/jwt/v4"
生成Token
定義claims
和serect
type MyClaims struct { Phone string `json:"phone"` jwt.RegisteredClaims // 注意!這是jwt-go的v4版本新增的,原先是jwt.StandardClaims } var MySecret = []byte("手寫的從前") // 定義secret,后面會用到
生成token
// 這里傳入的是手機號,因為我項目登陸用的是手機號和密碼 func MakeToken(phone string) (tokenString string, err error) { claim := MyClaims{ Phone: phone, RegisteredClaims: jwt.RegisteredClaims{ ExpiresAt: jwt.NewNumericDate(time.Now().Add(3 * time.Hour * time.Duration(1))), // 過期時間3小時 IssuedAt: jwt.NewNumericDate(time.Now()), // 簽發時間 NotBefore: jwt.NewNumericDate(time.Now()), // 生效時間 }} token := jwt.NewWithClaims(jwt.SigningMethodHS256, claim) // 使用HS256算法 tokenString, err = token.SignedString(MySecret) return tokenString, err }
解析token
func Secret() jwt.Keyfunc { return func(token *jwt.Token) (interface{}, error) { return []byte("手寫的從前"), nil // 這是我的secret } } func ParseToken(tokenss string) (*MyClaims, error) { token, err := jwt.ParseWithClaims(tokenss, &MyClaims{}, Secret()) if err != nil { if ve, ok := err.(*jwt.ValidationError); ok { if ve.Errors&jwt.ValidationErrorMalformed != 0 { return nil, errors.New("that's not even a token") } else if ve.Errors&jwt.ValidationErrorExpired != 0 { return nil, errors.New("token is expired") } else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 { return nil, errors.New("token not active yet") } else { return nil, errors.New("couldn't handle this token") } } } if claims, ok := token.Claims.(*MyClaims); ok && token.Valid { return claims, nil } return nil, errors.New("couldn't handle this token") }
參考:
JSON Web Token 入門教程
總結
原文鏈接:https://blog.csdn.net/weixin_44294408/article/details/122095919
相關推薦
- 2023-07-07 maven查看jar的pom引入來源
- 2022-03-23 解決plsql因事務未提交造成的鎖表問題_oracle
- 2023-06-17 tensorflow1.x和tensorflow2.x中的tensor轉換為字符串的實現_pytho
- 2022-09-06 C++詳細講解引用類型_C 語言
- 2022-01-08 Unity如何制作道具tips隨著屏幕邊界自適應變換位置,確保不超出屏幕的功能
- 2021-12-24 SQL注入詳解及防范方法_數據庫其它
- 2022-11-16 python3?如何解壓縮.gz文件_python
- 2022-01-04 localStorage本地存儲防止參數丟失
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支