Bootstrap

Go项目开发实战 - 用户 Token 的派发、存储和认证管理

上一篇文章「企业级项目,用户认证体系怎么设计?」我们详述了实现一个企业级产品的用户认证服务的整体思路

从这一节开始我们来演示如何按照思路实现一个用户认证体系,本节我们主要关注用户Token的生成、存储以及认证,下一节我们会专注Token的刷新、主动踢人下线和防盗检测。

本节内容大纲如下:

1cddbfe9831be4722add48fa044f7929.png

Token串的自解释性和生成规则

我们的用户认证体系里有两种Token:AccessToken以及刷新它用的RefreshToken。

021a5d872b9154209f0ad86aa15cfa1e.png 无论Token信息在产品的服务端有哪些构成信息,我们发放给客户端的都是随机的字符串,客户端访问服务端API时会携带着Token串来访问。

Token串的生成算法多种多样,简单的MD5一下子,复杂的会各种加密,在我们项目中使用的则是一个兼具安全和可解释性的Token生成算法

为每个用户生成的Token的算法,会用大端序的排列方式把用户ID放到固定位置后再进行AES加密,同时再追加一个类似salt串的随机字符串作为前缀,把16进制转换成字符串后一共有40个字符。

33c657a0f8d6226df3c14b768287d0f7.png

因为生成Token时UserID放在了固定的字节位置,所以服务端拿到Token后可以解密后再把UserID取出来,这样的话Token就具有了自解释性在系统存储挂掉的降级处理,或者是大数据分析应用日志、归因用户行为时都有一定帮助

解析Token的代码在教程里就不再占用篇幅了,大家订阅加入项目后访问下面GitHub仓库的代码文件可查看详细细节。

  • Token反解析出UserID的代码实现

Token的生成和存储

Token生成的流程解读

用户登录授权,在给用户发放Token前,服务端会存储三份信息用于会话管理和认证。它们分别是AccessToken、RefreshToken 和 UserSession 的缓存信息,其缓存结构如下:

384c2c175f846499fafbe42df49ebc2a.png

这个我们在上一节讨论过,其中UserSession是为用户的每个登录过的平台单独维护一份Session信息,根据它们的结构特点,我们选择对三种缓存采用以下结构:

  • AccessToken、RefreshToken 缓存以各自的Token值做为缓存Key的关键要素,使用Redis String存储JSON格式的Token信息

  • UserSession使用UserId做为缓存Key的关键要素部分,使用Redis 的Hash存储,Hash中以每个登录平台的Platform名为字段Key,存储相应用户JSON格式的Session信息,这样多个平台登录后的会话不会相互干扰。

Token生成逻辑的流程和内部细节我用一个顺序图给大家做了梳理,还有详细的代码指南

af3dc8309176f2e64058198a097c67dd.png

这部分内容请扫码订阅专栏查看完整版

7af6537abe077edfebfc9422bbbb9159.png

项目中有完整的实现步骤以及Token生成、验证的测试用例供我们边调试代码边理解

704585c50ac27a1c7c4a762aff9373ab.png


Token的校验

拿我们上面获得的AccessToken来试验Token的校验,因为需要在Header中带上Token, 需使用curl来发起请求,大家自己测试时可选择使用POSTMAN等工具。

curl --header "Content-Type: application/json" \
  --header "go-mall-token: 3d7454dd7fe557917a0c195fceebd8c786acc97e" \
  http://localhost:8080/building/token-auth-test

请求的结果如下:

0b6dbc0990fdf1e2519a81bf82d9d8f7.png

大家加入项目后动手实践时可以故意把Token写错看一下其他效果。

总结

本节的代码版本号为c11,版本切换操作命令如下:

git fetch --tags
git checkout tags/c11

访问 https://github.com/go-study-lab/go-mall/compare/c10...c11 能看本章节的详细代码。

98a122fc06d7d31245f5347df0b7bbe8.png 下节课我们主要聊Token的刷新以及踢人下线和Token被盗检测功能。这部分内容在专栏中也已经更新,感兴趣的请扫码订阅专栏阅读 360311ac23aa07a317f0d0ad4c2dbef3.png

本专栏分为五大部分,大部分内容已经更新完成

30ac285e39d2861115545cea6438f08f.png
  • 第一部分介绍让框架变得好用的诸多实战技巧,比如通过自定义日志门面让项目日志更简单易用、支持自动记录请求的追踪信息和程序位置信息、通过自定义Error在实现Go error接口的同时支持给给错误添加错误链,方便追溯错误源头。

  • 第二部分:讲解项目分层架构的设计和划分业务模块的方法和标准,让你以后无论遇到什么项目都能按这套标准自己划分出模块和逻辑分层。后面几个部分均是该部分所讲内容的实践。

  • 第三部分:设计实现一个套支持多平台登录,Token泄露检测、同平台多设备登录互踢功能的用户认证体系,这套用户认证体系既可以在你未来开发产品时直接应用

  • 第四部分:商城app C端接口功能的实现,强化分层架构实现的讲解,这里还会讲解用责任链、策略和模版等设计模式去解决订单结算促销、支付方式支付场景等多种多样的实际问题。

  • 第五部分:单元测试、项目Docker镜像、K8s部署和服务保障相关的一些基础内容和注意事项

扫描上方二维码或者访问 https://xiaobot.net/p/golang 即刻订阅

;