使用go-zero在Go中快速实现JWT认证
JWT(JSON Web Token)是一种用于进行认证和授权的标准化方法,通常用于 Web 应用程序中的身份验证和授权。在使用 JWT 进行身份验证时,应用程序会向用户提供一个 JWT,用户在每次请求时都将这个 JWT 发送到应用程序,以便应用程序可以通过验证 JWT 来确定用户的身份。
Go-Zero 是一款基于 Golang 的微服务开发框架,它内置了大量的开箱即用的功能,如网关、服务发现、配置中心等。Go-Zero 还提供了许多工具,如 API 代码生成器、客户端生成器等,使开发人员能够快速打造高性能、稳定、易维护的微服务应用程序。
在本文中,我们将介绍如何使用 Go-Zero 快速实现 JWT 认证。
1. 安装依赖库
首先,我们需要在项目中安装以下依赖库:
go get -u github.com/dgrijalva/jwt-go
2. 创建 JWT Middleware
在 Go-Zero 中,我们可以使用 Middleware 来实现 JWT 认证。我们可以创建一个 JWT Middleware 来处理所有需要认证的请求。首先,我们需要创建一个 JWT 配置结构体:
// JWT 配置结构体
type JWTConfig struct {
SigningKey []byte
}
SigningKey 是 JWT 的签名密钥,我们可以在配置文件中配置。
接下来,我们需要创建一个 JWT Middleware,它负责验证 JWT 并将用户信息添加到上下文中:
// JWT Middleware
func JwtMiddleware(cfg *JWTConfig) middleware.Middleware {
return func(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
tokenString := r.Header.Get("Authorization")
if tokenString == "" {
http.Error(w, "Authorization token not found", http.StatusUnauthorized)
return
}
token, err := jwt.ParseWithClaims(tokenString, &jwt.StandardClaims{}, 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 cfg.SigningKey, nil
})
if err != nil {
http.Error(w, err.Error(), http.StatusUnauthorized)
return
}
if !token.Valid {
http.Error(w, "Invalid authorization token", http.StatusUnauthorized)
return
}
claims, ok := token.Claims.(*jwt.StandardClaims)
if !ok {
http.Error(w, "Invalid authorization token", http.StatusUnauthorized)
return
}
ctx := context.WithValue(r.Context(), "userId", claims.Subject)
next(w, r.WithContext(ctx))
}
}
}
该函数接受一个 JWTConfig 结构体并返回一个 Middleware 函数。中间件函数检查 Authorization 头中是否包含 JWT。如果没有,它返回 HTTP 401 错误。如果存在,它会使用 SigningKey 进行解密。如果解密失败或 JWT 无效,则返回 HTTP 401 错误。否则,它将用户信息添加到上下文中,并将请求传递给下一个处理程序。
3. 使用 JWT Middleware
现在我们已经创建了 JWT Middleware,下一步是将它应用到需要认证的请求中。我们可以使用 Go-Zero 的 Middleware 方法将中间件添加到路由处理程序中:
// 添加 JWT Middleware 到路由
r := httpx.NewRouter()
r.GET("/api/hello", JwtMiddleware(&JWTConfig{SigningKey: []byte("signing key")})(HelloHandler))
在这里,我们将 JwtMiddleware 作为处理程序的 个参数传递给 NewRouter 方法。如果请求到达 "/api/hello" 路由路径,JwtMiddleware 将首先运行。如果认证通过,则 HelloHandler 函数将被调用。
4. 创建 JWT
现在,我们已经创建了 JWT Middleware 并将其应用到需要认证的请求中。下一步是创建 JWT 并将其提供给客户端。我们可以创建一个 JWT 生成函数,该函数为具有用户 ID 的 JWT 签名:
// JWT 生成函数
func GenerateJWT(userId string, signingKey []byte, expireTime time.Duration) (string, error) {
claims := jwt.StandardClaims{
ExpiresAt: time.Now().Add(expireTime).Unix(),
Subject: userId,
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, err := token.SignedString(signingKey)
if err != nil {
return "", err
}
return tokenString, nil
}
该函数接受用户 ID,签名密钥和 JWT 的过期时间,生成带有用户 ID 和过期时间的 JWT 并进行签名。然后,它将 JWT 返回给调用者。
在客户端代码中,我们可以通过调用此函数来获取 JWT 并将其发送到服务器:
jwt, err := GenerateJWT("user123", []byte("signing key"), time.Hour)
if err != nil {
// 处理错误
}
req, err := http.NewRequest("GET", "/api/hello", nil)
if err != nil {
// 处理错误
}
req.Header.Set("Authorization", jwt)
resp, err := http.DefaultClient.Do(req)
if err != nil {
// 处理错误
}
// 处理响应
5. 结论
在本文中,我们介绍了如何使用 Go-Zero 快速实现 JWT 认证。我们创建了一个 JWT Middleware,该中间件检查 Authorization 头中是否包含 JWT 并验证 JWT。我们还创建了一个 JWT 生成函数,该函数为具有用户 ID 的 JWT 签名。通过使用这些函数,我们可以快速、简单地实现 JWT 认证。
