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()
        }
}