Gin(十五):JWT使用(续)
Gin 教程叕来了(说好的大结局呢?),这次主要是来说明 JWT
存在的一些问题和解决方案。如果你还不知道 JWT
是什么,建议了解一下,也可以翻翻前面的文章看看。
💊问题所在
上次写 JWT
的时候,和群里的小伙伴讨论,有小伙伴提出了一些问题,用户修改密码或者注销账户怎么办?
是啊,怎么办?
我们都知道 JWT
是否有效,靠的是失效时间,而且服务器不对用户 JWT
进行保存,也就是一旦签发了的 JWT
,服务器失去了对其的控制权,只能等其过期而失效。如果这样,那么用户修改密码或者注销之后,之前的 JWT
仍旧还可以使用,那么就会带来安全风险。
于是乎,我默默的打开了百(gu)度(ge)
🙄🙄🙄🙄🙄🙄
你们为什么要把 JWT
存在 redis
里?
这是什么操作?一旦服务器去保存 JWT
,还用什么 JWT
?普通 token
就完全可以了啊,何必多此一举。
以上就是我们在使用 JWT
的时候产生的问题。
🀄解决问题
既然有了问题,就要解决。
再次回顾一下 JWT
的使用流程。
-
浏览器发出登录请求,将账号和密码提交到服务器;
-
服务器创建
JWT
并且加密(并不是全部加密,仅仅加密VERIFY SIGNATURE
); -
将
JWT
返回浏览器; -
访问需要授权的接口,将
JWT
携带在Header; -
校验
JWT
,并且从JWT
获取JWT
; -
响应浏览器。
上面的六个步骤就是 JWT
使用的过程。服务器只做了两步,生成 JWT
和校验 JWT
。而我们解决上述提出的问题,就在服务器端解决。
我们都知道在加密的时候服务器端会保存一个密钥,而校验解密的时候就需要这个密钥,这个密钥就是我们解决该问题的 KEY 。
如果我们把密钥设成动态的,用户密码修改或者注销的时候,该密钥就会发生改变,那么之前签发的 JWT
无法使用新的密钥来解密了,也就意味着之前的密钥已经失效了。而这个动态密钥应该保证独立,每个用户的密钥应该是不一样的,该用户的密钥只负责该用户的 JWT
。
于是乎,问题似乎已经解决了,我们可以在数据库用户表中设置一个单独的字段来标识,每次发生密码修改或者账号注销的时候,只需要修改该字段就可以保证之前的JWT
失效。或者使用用户的密码作为密钥。
部分代码
UserHandler.go
// 通过密码和保留字段加密 var jwtSecret = []byte(config.Secret + u.Password) token, err := tokenClaims.SignedString(jwtSecret)
其中 config.Secret
是我们服务器上的固定密钥。
Auth.go
// 分割出来载体 payload := strings.Split(token, ".") bytes, e := jwt.DecodeSegment(payload[1]) if e != nil { println(e.Error()) } content := "" for i := 0; i < len(bytes); i++ { content += string(bytes[i]) } split := strings.Split(content, ",") id := strings.SplitAfter(split[2], ":") i := strings.Split(id[1], "\\u") i = strings.Split(i[1], "\"") ID, err := strconv.Atoi(i[0]) if err != nil { println(err.Error()) } user := model.User{} user.ID = uint(ID) u := model.User.QueryById(user) jwtToken, err := jwt.ParseWithClaims(token, &jwt.StandardClaims{}, func(token *jwt.Token) (i interface{}, e error) { return []byte(config.Secret + u.Password), nil })
这里就不展示全部代码了。大家可以看 Github gin_jwt_2 分支上查看。
本文来自博客园,作者:youngxhui,转载请注明原文链接:https://www.cnblogs.com/youngxhui/p/17730469.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通