Gin Jwt Middleware
JWT in golang
golang中的jwt包一般是使用 github.com/dgrijalva/jwt-go
, 而且godoc中已经有些example,这里只是记录一下使用
jwt.StandardClaims的情况。
func parseToken(tokenString string) (*jwt.StandardClaims, error) {
token, err := jwt.ParseWithClaims(tokenString, &jwt.StandardClaims{}, func(t *jwt.Token) (interface{}, error) {
return jwtKey, nil
})
if err != nil {
log.Errorf("error: %v", err)
return nil, fmt.Errorf("failed to parse the token string: %s", tokenString)
}
log.Printf("claims: %v", token.Claims)
if claims, ok := token.Claims.(*jwt.StandardClaims); ok && token.Valid {
return claims, nil
} else {
return nil, errors.Wrap(fmt.Errorf("failed to valiate the token"), "failed")
}
}
这个方法会把一个string通过jwt的parsewithclaims恢复成StandardClaims,如果有错误会返回相应的error,这样的话,在middleware中可以 在req header中取到jwt然后尝试parse一下从而知道请求中的是valid的。
比如可以这样写
func JwtAuth() gin.HandlerFunc {
return func(c *gin.Context) {
authHeader := c.Request.Header.Get("Authorization")
log.Printf("auth header: %v \n", authHeader)
if authHeader == "" {
c.JSON(http.StatusUnauthorized, gin.H{
"msg": "Unauthorized",
})
c.Abort()
return
}
mc, err := parseToken(strings.ReplaceAll(authHeader, "Bearer ", ""))
log.Printf("token : %+v \n", mc)
if err != nil {
log.Errorf("token error: %v", err)
c.JSON(http.StatusUnauthorized, gin.H{
"msg": "invalid",
})
c.Abort()
return
}
if !mc.VerifyExpiresAt(time.Now().Unix(), true) {
c.JSON(http.StatusUnauthorized, gin.H{
"msg": "token expired",
})
c.Abort()
return
}
log.Printf("current user: %s", mc.Subject)
c.Next()
}
}