JWT实战疑问

infoBrainSys · 2023-04-27 17:38:49 · 2439 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2023-04-27 17:38:49 的主题,其中的信息可能已经有所发展或是发生改变。

想巩固一下学到的东西,就想动手写一个注册登录的小项目,结果在JWT鉴权过程中卡住了,问题如下: POST访问/login获得token,随后携带tokenGET访问/token使用工具验证token正常签发,然后在i鉴权中间件里走了Authorization token is wrong分支,请问这是为什么? 另外有个小问题就是,签发的token仅仅丢到了客户端,不需要保存吗?

  • package: github.com/golang-jwt/jwt/v5

model

type User struct {
    *gorm.Model
    UserName string `form:"userName"`
    PassWord string `form:"passWord"`
}

JWT SignedToken

func (j *JWT) Signed(user *models.User) string {
    v, _ := vp.GetCfg()
    key := v.GetString("kwt.key")

    sg := jwt.NewWithClaims(jwt.SigningMethodHS256, &ArkClaims{
        MapClaims: jwt.MapClaims{
            "iss": "ark",                            // 签发者
            "sub": user.UserName,                    // 受众
            "iat": time.Now().Unix(),                // 签发时间
            "exp": time.Now().Add(time.Hour).Unix(), // 过期时间
        },
    })
    token, _ := sg.SignedString([]byte(key))

    return token
}

JWT AuthToken

func (j *JWT) Auth(tokenString string) error {
    vi, _ := vp.GetCfg()
    key := vi.GetString("jwt.key")

    token, _ := jwt.ParseWithClaims(tokenString, &ArkClaims{}, func(token *jwt.Token) (interface{}, error) {
        if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
            return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
        }
        return key, nil
    })
    if !token.Valid {
        return errors.New("token not valid")
    }
    return nil
}

Auth Middlware

func AuthMiddleware() gin.HandlerFunc {
    return func(ctx *gin.Context) {

        // 获取请求头中的 Authorization
        BearerToken := ctx.GetHeader("Authorization")
        if BearerToken == "" {
            ctx.JSON(http.StatusUnauthorized, gin.H{
                "msg": "Authorization token is missing",
            })
            ctx.Abort()
            return
        }
        token := BearerToken[len("Bearer "):]
        fmt.Println(token)

        // 验证 token 是否有效
        newJWT := auth.NewJWT()
        err := newJWT.Auth(token)
        if err != nil {
            ctx.JSON(http.StatusUnauthorized, gin.H{
                "msg": "Authorization token is wrong",
            })
            ctx.Abort()
            return
        }

        ctx.Next()
    }
}

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2439 次点击  
加入收藏 微博
2 回复  |  直到 2023-04-28 09:40:58
xwszt
xwszt · #1 · 2年之前

1、jwt的token不需要保存在服务器端(验证的过程就是解密,如果解密出错,token就是错的,最好在签名的时候加上客户端的唯一标识,比如IP地址啥的,以防token拷贝在不同的主机上访问服务);

2、在auth阶段,你在header里读出了token,但是这个token加了“Bear ”,需要把这个去掉后再验证token。你的代码中少了这段代码;

infoBrainSys
infoBrainSys · #2 · 2年之前
xwsztxwszt #1 回复

1、jwt的token不需要保存在服务器端(验证的过程就是解密,如果解密出错,token就是错的,最好在签名的时候加上客户端的唯一标识,比如IP地址啥的,以防token拷贝在不同的主机上访问服务); 2、在auth阶段,你在header里读出了token,但是这个token加了“Bear ”,需要把这个去掉后再验证token。你的代码中少了这段代码;

谢谢指点,我在验证逻辑中用切片吧Bearer去掉了。错误原因是:签名用了[]byte(key),验证用的key,虽然打印出来两者无异,但是这小细节实在是浪费了很多精力。

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传