eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.UQmqAUhUrpDVV2ST7mZKyLTomVfg7sYkEjmdDI5XF8Q
{'typ': 'JWT','alg': 'HS256'}
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
{"sub": "1234567890","name": "John Doe","admin": true}然后将其进行base64加密,得到Jwt的第二部分
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9signature
header (base64后的)
payload (base64后的)
secret
需要base64加密后的header和base64加密后的payload使用"."连接组成的字符串(头部在前),
然后通过header中声明的加密方式进行加secret组合加密,
构成了jwt的第三部分
举例
UQmqAUhUrpDVV2ST7mZKyLTomVfg7sYkEjmdDI5XF8Q
fetch('api/user/1', { headers: {'Authorization': 'Bearer ' + token }})服务端会验证token
如果验证通过,就会返回相应的资源
调用包 https://github.com/tutengdihuang/jwt
单例模式
var jwtIns *JwtAuth
type JwtAuth struct {
Lock *sync.Mutex
algorithm *jwt.Algorithm
claimsMap map[string]*jwt.Claims //key: userID
}
func GetJwtAuth() *JwtAuth {
if jwtIns == nil {
once := sync.Once{}
once.Do(
func() {
if jwtIns == nil {
jwtIns = new(JwtAuth)
jwtIns.Lock = new(sync.Mutex)
jwtIns.claimsMap = make(map[string]*jwt.Claims)
secret := config_center.GetViperConf().Sub("jwt").GetString("secret")
algorithm := jwt.HmacSha256(secret)
jwtIns.algorithm = &algorithm
}
})
}
return jwtIns
}
var jwtClaimUserKey = "username"
var jwtClaimUserIdKey = "id"
func (this *JwtAuth) GetToken(userName string, id int) (token string, err error) {
claim := jwt.NewClaim()
claim.Set(jwtClaimUserKey, userName)
claim.Set(jwtClaimUserIdKey, strconv.Itoa(id))
//claim.SetTime("expire", time.Now().Add(30*time.Minute))
idstr := strconv.Itoa(id)
this.Lock.Lock()
defer this.Lock.Unlock()
this.claimsMap[idstr] = claim
token, err = this.algorithm.Encode(claim)
return
}
func (this *JwtAuth) Validate(idstr, token string) bool {
this.Lock.Lock()
defer this.Lock.Unlock()
if _, ok := this.claimsMap[idstr]; !ok {
return false
}
if this.algorithm.Validate(token) != nil {
return false
}
return true
}
func (this *JwtAuth) TokenDecode(token string) (string, int, error) {
claim, err := this.algorithm.Decode(token)
if err != nil {
return "", 0, err
}
userName, err := claim.Get(jwtClaimUserKey)
if err != nil {
return "", 0, err
}
idStr, err := claim.Get(jwtClaimUserIdKey)
if err != nil {
return "", 0, err
}
id, _ := strconv.Atoi(idStr)
return userName, id, nil
}
func (this *JwtAuth) TokenRemove(id string) {
this.Lock.Lock()
defer this.Lock.Unlock()
delete(this.claimsMap, id)
}