基于Golang Go语言中的go-zero轻松实现JWT认证

发布于 1周前 作者 vueper 来自 Go语言

基于Golang Go语言中的go-zero轻松实现JWT认证

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

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

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

1. 客户端获取 JWT Token

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

type JwtTokenRequest struct {
}

type JwtTokenResponse struct { AccessToken string json:"access_token" AccessExpire int64 json:"access_expire" RefreshAfter int64 json:"refresh_after" // 建议客户端刷新 token 的绝对时间 }

type GetUserRequest struct { UserId string json:"userId" }

type GetUserResponse struct { Name string json:"name" }

service jwt-api { @server( handler: JwtHandler ) post /user/token(JwtTokenRequest) returns (JwtTokenResponse) }

@server( jwt: JwtAuth ) service jwt-api { @server( handler: GetUserHandler ) post /user/info(GetUserRequest) returns (GetUserResponse) }

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


func (l *JwtLogic) Jwt(req types.JwtTokenRequest) (*types.JwtTokenResponse, error) {
	var accessExpire = l.svcCtx.Config.JwtAuth.AccessExpire
now := time.Now().Unix()
accessToken, err := l.GenToken(now, l.svcCtx.Config.JwtAuth.AccessSecret, nil, accessExpire)
if err != nil {
	return nil, err
}

return &types.JwtTokenResponse{
AccessToken:  accessToken,
AccessExpire: now + accessExpire,
RefreshAfter: now + accessExpire/2,

}, nil }

func (l *JwtLogic) GenToken(iat int64, secretKey string, payloads map[string]interface{}, seconds int64) (string, error) { claims := make(jwt.MapClaims) claims[“exp”] = iat + seconds claims[“iat”] = iat for k, v := range payloads { claims[k] = v }

token := jwt.New(jwt.SigningMethodHS256)
token.Claims = claims

return token.SignedString([]byte(secretKey))

}

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

Name: jwt-api
Host: 0.0.0.0
Port: 8888
JwtAuth:
  AccessSecret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  AccessExpire: 604800

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

➜ curl --location --request POST '127.0.0.1:8888/user/token'
{"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 如下:
func (l *GetUserLogic) GetUser(req types.GetUserRequest) (*types.GetUserResponse, error) {
	return &types.GetUserResponse{Name: "kim"}, nil
}
  • 我们先不带 JWT Authorization header 请求头测试下,返回 http status code 是 401,符合预期。
➜ curl -w  "\nhttp: %{http_code} \n" --location --request POST '127.0.0.1:8888/user/info' \
--header 'Content-Type: application/json' \
--data-raw '{
    "userId": "a"
}'

http: 401

  • 加上 Authorization header 请求头测试。
➜ 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 '{
    "userId": "a"
}'
{"name":"kim"}
http: 200

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

8. 项目地址

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

9. 微信交流群

微信交流群


更多关于基于Golang Go语言中的go-zero轻松实现JWT认证的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于基于Golang Go语言中的go-zero轻松实现JWT认证的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中,利用go-zero框架实现JWT(JSON Web Tokens)认证是一种高效且常见的方法。go-zero作为一个微服务框架,提供了丰富的组件和工具,使得集成JWT认证变得相对简单。

首先,你需要引入JWT相关的库,如github.com/dgrijalva/jwt-go,这个库提供了JWT的创建、解析和验证等功能。

接着,在go-zero的服务中,你可以创建一个中间件来处理JWT的验证。中间件会在每个请求到达业务逻辑之前,检查请求头中是否包含有效的JWT。如果JWT有效,中间件会将用户信息(如用户ID)提取出来,并附加到请求的上下文中,供后续的业务逻辑使用。

为了生成JWT,你需要在用户登录或其他需要认证的场景中,创建一个包含用户信息和过期时间的JWT字符串,并将其返回给客户端。客户端在后续的请求中,需要将这个JWT字符串放在请求头中,以便服务器进行验证。

此外,go-zero还提供了API网关组件,你可以将JWT验证的逻辑放在网关层,这样所有的微服务都可以共享这个认证机制,而无需在每个服务中都实现一遍。

总的来说,利用go-zero框架和JWT库,你可以轻松地实现一个安全、高效的认证机制。这不仅提高了系统的安全性,还简化了认证逻辑的实现和维护。如果你需要更详细的实现步骤或示例代码,可以参考go-zero的官方文档或社区资源。

回到顶部