经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Go语言 » 查看文章
如何利用go-zero在Go中快速实现JWT认证
来源:cnblogs  作者:Kevin Wan  时间:2020/11/9 16:09:48  对本文有异议

关于JWT是什么,大家可以看看官网,一句话介绍下:是可以实现服务器无状态的鉴权认证方案,也是目前最流行的跨域认证解决方案。

要实现JWT认证,我们需要分成如下两个步骤

  • 客户端获取JWT token。
  • 服务器对客户端带来的JWT token认证。

1. 客户端获取JWT Token

我们定义一个协议供客户端调用获取JWT token,我们新建一个目录jwt然后在目录中执行 goctl api -o jwt.api,将生成的jwt.api改成如下:

  1. type JwtTokenRequest struct {
  2. }
  3. type JwtTokenResponse struct {
  4. AccessToken string `json:"access_token"`
  5. AccessExpire int64 `json:"access_expire"`
  6. RefreshAfter int64 `json:"refresh_after"` // 建议客户端刷新token的绝对时间
  7. }
  8. type GetUserRequest struct {
  9. UserId string `json:"userId"`
  10. }
  11. type GetUserResponse struct {
  12. Name string `json:"name"`
  13. }
  14. service jwt-api {
  15. @handler JwtHandler
  16. post /user/token(JwtTokenRequest) returns (JwtTokenResponse)
  17. }
  18. @server(
  19. jwt: JwtAuth
  20. )
  21. service jwt-api {
  22. @handler JwtHandler
  23. post /user/info(GetUserRequest) returns (GetUserResponse)
  24. }

在服务jwt目录中执行:goctl api go -api jwt.api -dir .
打开jwtlogic.go文件,修改 func (l *JwtLogic) Jwt(req types.JwtTokenRequest) (*types.JwtTokenResponse, error) { 方法如下:

  1. func (l *JwtLogic) Jwt(req types.JwtTokenRequest) (*types.JwtTokenResponse, error) {
  2. var accessExpire = l.svcCtx.Config.JwtAuth.AccessExpire
  3. now := time.Now().Unix()
  4. accessToken, err := l.GenToken(now, l.svcCtx.Config.JwtAuth.AccessSecret, nil, accessExpire)
  5. if err != nil {
  6. return nil, err
  7. }
  8. return &types.JwtTokenResponse{
  9. AccessToken: accessToken,
  10. AccessExpire: now + accessExpire,
  11. RefreshAfter: now + accessExpire/2,
  12. }, nil
  13. }
  14. func (l *JwtLogic) GenToken(iat int64, secretKey string, payloads map[string]interface{}, seconds int64) (string, error) {
  15. claims := make(jwt.MapClaims)
  16. claims["exp"] = iat + seconds
  17. claims["iat"] = iat
  18. for k, v := range payloads {
  19. claims[k] = v
  20. }
  21. token := jwt.New(jwt.SigningMethodHS256)
  22. token.Claims = claims
  23. return token.SignedString([]byte(secretKey))
  24. }

在启动服务之前,我们需要修改etc/jwt-api.yaml文件如下:

  1. Name: jwt-api
  2. Host: 0.0.0.0
  3. Port: 8888
  4. JwtAuth:
  5. AccessSecret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  6. AccessExpire: 604800

启动服务器,然后测试下获取到的token。

  1. ? curl --location --request POST '127.0.0.1:8888/user/token'
  2. {"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDEyNjE0MjksImlhdCI6MTYwMDY1NjYyOX0.6u_hpE_4m5gcI90taJLZtvfekwUmjrbNJ-5saaDGeQc","access_expire":1601261429,"refresh_after":1600959029}

2. 服务器验证JWT token

  1. 在api文件中通过jwt: JwtAuth标记的service表示激活了jwt认证。
  2. 可以阅读rest/handler/authhandler.go文件了解服务器jwt实现。
  3. 修改getuserlogic.go如下:
  1. func (l *GetUserLogic) GetUser(req types.GetUserRequest) (*types.GetUserResponse, error) {
  2. return &types.GetUserResponse{Name: "kim"}, nil
  3. }
  • 我们先不带JWT Authorization header请求头测试下,返回http status code是401,符合预期。
  1. ? curl -w "\nhttp: %{http_code} \n" --location --request POST '127.0.0.1:8888/user/info' --header 'Content-Type: application/json' --data-raw '{
  2. "userId": "a"
  3. }'
  4. http: 401
  • 加上Authorization header请求头测试。
  1. ? curl -w "\nhttp: %{http_code} \n" --location --request POST '127.0.0.1:8888/user/info' --header 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDEyNjE0MjksImlhdCI6MTYwMDY1NjYyOX0.6u_hpE_4m5gcI90taJLZtvfekwUmjrbNJ-5saaDGeQc' --header 'Content-Type: application/json' --data-raw '{
  2. "userId": "a"
  3. }'
  4. {"name":"kim"}
  5. http: 200

综上所述:基于go-zero的JWT认证完成,在真实生产环境部署时候,AccessSecret, AccessExpire, RefreshAfter根据业务场景通过配置文件配置,RefreshAfter 是告诉客户端什么时候该刷新JWT token了,一般都需要设置过期时间前几天。

3. 项目地址

https://github.com/tal-tech/go-zero

好未来技术

原文链接:http://www.cnblogs.com/kevinwan/p/13877426.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号