jwt token 生成
func getJwtToken(secretKey string, iat, seconds int64, payload int64) (string, error) {
claims := make(jwt.MapClaims)
claims["exp"] = iat + seconds
claims["iat"] = iat
claims["payload"] = payload
token := jwt.New(jwt.SigningMethodHS256)
token.Claims = claims
return token.SignedString([]byte(secretKey))
}
其他中间件获取 jwt 中信息
func (m *PermissionMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
payload := r.Context().Value("payload")
var userId int64
if jsonPayload, ok := payload.(json.Number); ok {
if int64UserId, err := jsonPayload.Int64(); err == nil {
userId = int64UserId
fmt.Println("当前用户ID: ", userId)
} else {
response.Response(w, nil, errors.New("用户信息获取失败"))
return
}
} else {
response.Response(w, nil, errors.New("用户信息获取失败"))
return
}
if true == false {
response.Response(w, nil, errors.New("权限不足"))
return
}
next(w, r)
}
}
说明
- 可以看到中间件中可以直接
r.Context().Value("payload")
的形式获取我们在写入到 jwt 中的信息,注意这里的 payload
名称 和 jwt 设置的是保持一致的。这个 jwt 的解析过程在 gozero 的 jwt
组件中已经做了,所以我们可以方便的从 request
中获取。具体的jiwt 解析可以参考 gozero 的 rest/handler/authhandler.go
,可以看到已经通过 context.WithValue(ctx, k, v)
写入了值
parser := token.NewTokenParser()
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
tok, err := parser.ParseToken(r, secret, authOpts.PrevSecret)
if err != nil {
unauthorized(w, r, err, authOpts.Callback)
return
}
if !tok.Valid {
unauthorized(w, r, errInvalidToken, authOpts.Callback)
return
}
claims, ok := tok.Claims.(jwt.MapClaims)
if !ok {
unauthorized(w, r, errNoClaims, authOpts.Callback)
return
}
ctx := r.Context()
for k, v := range claims {
switch k {
case jwtAudience, jwtExpire, jwtId, jwtIssueAt, jwtIssuer, jwtNotBefore, jwtSubject:
default:
ctx = context.WithValue(ctx, k, v)
}
}
next.ServeHTTP(w, r.WithContext(ctx))
})
}
- 我们在通过
payload := r.Context().Value("payload")
获取对应的值的类型,这个和我们设置 jwt token 是相关的,默认整个 jwt token 解析出来的是 json 的格式的,int/int64 写入 jwt 解析之后是 json.Number
类型,string 写入的话,解析出来的还是 string,所以获取值时需要有一个转换的过程。