Go语言JWT身份认证完整实现指南
最近在学习Go语言的JWT身份认证实现,但在实际开发中遇到几个问题:
- 如何正确生成和解析JWT token?
- 在Go中应该如何安全地存储和传输JWT?
- 有没有推荐的库或最佳实践来处理token过期和刷新?
- 如何结合中间件实现路由的权限控制?
希望能得到一份完整的实现指南,包括代码示例和常见问题的解决方案。
2 回复
使用Go实现JWT认证,推荐使用github.com/golang-jwt/jwt库。步骤:1.生成密钥;2.创建token(包含用户信息、过期时间);3.签名并返回给客户端;4.中间件验证token有效性。注意设置合理的过期时间,使用安全的签名算法(如HS256)。示例代码可在官方文档找到。
Go语言JWT身份认证完整实现指南
JWT(JSON Web Token)是一种用于安全传输信息的开放标准,常用于身份认证和授权。
核心概念
JWT由三部分组成:
- Header(头部)
- Payload(载荷)
- Signature(签名)
实现步骤
1. 安装依赖
go get github.com/golang-jwt/jwt/v4
2. 定义JWT结构体
import "github.com/golang-jwt/jwt/v4"
type Claims struct {
UserID int `json:"user_id"`
Username string `json:"username"`
jwt.RegisteredClaims
}
var jwtKey = []byte("your-secret-key")
3. 生成JWT Token
func GenerateToken(userID int, username string) (string, error) {
expirationTime := time.Now().Add(24 * time.Hour)
claims := &Claims{
UserID: userID,
Username: username,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(expirationTime),
IssuedAt: jwt.NewNumericDate(time.Now()),
Issuer: "your-app-name",
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString(jwtKey)
}
4. 验证JWT Token
func ValidateToken(tokenString string) (*Claims, error) {
claims := &Claims{}
token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
return jwtKey, nil
})
if err != nil {
return nil, err
}
if !token.Valid {
return nil, fmt.Errorf("invalid token")
}
return claims, nil
}
5. HTTP中间件
func AuthMiddleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
tokenString := r.Header.Get("Authorization")
if tokenString == "" {
http.Error(w, "Authorization header required", http.StatusUnauthorized)
return
}
// 去掉"Bearer "前缀
if len(tokenString) > 7 && tokenString[:7] == "Bearer " {
tokenString = tokenString[7:]
}
claims, err := ValidateToken(tokenString)
if err != nil {
http.Error(w, "Invalid token", http.StatusUnauthorized)
return
}
// 将用户信息存入上下文
ctx := context.WithValue(r.Context(), "user", claims)
next.ServeHTTP(w, r.WithContext(ctx))
}
}
6. 使用示例
func loginHandler(w http.ResponseWriter, r *http.Request) {
// 验证用户凭据
userID := 1
username := "john"
token, err := GenerateToken(userID, username)
if err != nil {
http.Error(w, "Failed to generate token", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{
"token": token,
})
}
func protectedHandler(w http.ResponseWriter, r *http.Request) {
claims, ok := r.Context().Value("user").(*Claims)
if !ok {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
w.Write([]byte(fmt.Sprintf("Hello %s!", claims.Username)))
}
安全建议
- 使用强密钥(至少32字符)
- 设置合理的过期时间
- 使用HTTPS传输
- 定期轮换密钥
- 在Payload中不要存储敏感信息
完整路由设置
func main() {
http.HandleFunc("/login", loginHandler)
http.HandleFunc("/protected", AuthMiddleware(protectedHandler))
log.Println("Server starting on :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
这个实现提供了完整的JWT身份认证流程,包括Token生成、验证和中间件保护。

