使用 github.com/golang-jwt/jwt
实现 JWT(JSON Web Token)可以有效地进行用户身份验证,这个功能往往在接口前后端分离的应用中经常用到。以下是一个基本的示例,演示如何在 Gin 框架中实现 JWT 认证。
目录结构
/hello-gin
│
├── cmd/
│ └── main.go
├── api/
│ ├── routes.go
│ └── auth.go
└── middleware/
└── jwt.go
└── models/
└── user.go
1. 安装依赖
首先,你需要安装 github.com/golang-jwt/jwt
包:
go get github.com/golang-jwt/jwt
2. cmd/main.go
主程序,设置路由和中间件。
package main
import (
"hello-gin/api"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
// 注册路由
api.RegisterRoutes(r)
// 启动服务器
r.Run(":8080")
}
3. api/routes.go
定义路由,包括登录和受保护的资源。
package api
import (
"github.com/gin-gonic/gin"
"hello-gin/middleware"
)
func RegisterRoutes(r *gin.Engine) {
r.POST("/login", Login)
// 受保护的路由
protected := r.Group("/protected")
protected.Use(middleware.JWTAuthMiddleware())
{
protected.GET("/hello", Hello)
}
}
4. api/auth.go
处理登录和生成 JWT 的逻辑。
package api
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt"
"time"
)
var jwtSecret = []byte("your_secret_key")
// User 表示一个简单的用户结构
type User struct {
Username string `json:"username"`
Password string `json:"password"`
}
// Login 处理用户登录并返回 JWT
func Login(c *gin.Context) {
var user User
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"})
return
}
// 这里简单的硬编码验证,实际使用中应查询数据库
if user.Username != "testuser" || user.Password != "testpassword" {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid credentials"})
return
}
// 生成 JWT
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"username": user.Username,
"exp": time.Now().Add(time.Hour * 72).Unix(),
})
tokenString, err := token.SignedString(jwtSecret)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not generate token"})
return
}
c.JSON(http.StatusOK, gin.H{"token": tokenString})
}
// Hello 是一个受保护的路由示例
func Hello(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "Hello, authenticated user!"})
}
5. middleware/jwt.go
实现 JWT 验证中间件。
package middleware
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt"
)
var jwtSecret = []byte("your_secret_key")
// JWTAuthMiddleware 验证 JWT 的中间件
func JWTAuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
tokenString := c.Request.Header.Get("Authorization")
if tokenString == "" {
c.JSON(http.StatusUnauthorized, gin.H{"error": "No token provided"})
c.Abort()
return
}
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, http.ErrNotSupported
}
return jwtSecret, nil
})
if err != nil || !token.Valid {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"})
c.Abort()
return
}
// 令牌有效,继续处理请求
c.Next()
}
}
6. 测试应用
在项目根目录下运行:
go run cmd/main.go
登录
使用 Postman 或 cURL 发送 POST 请求到 http://localhost:8080/login
,请求体示例:
{
"username": "testuser",
"password": "testpassword"
}
如果登录成功,将返回一个 JWT:
{
"token": "your_jwt_token"
}
访问受保护的资源
使用返回的 JWT 作为 Authorization
头部的值,发送 GET 请求到 http://localhost:8080/protected/hello
:
curl -H "Authorization: your_jwt_token" http://localhost:8080/protected/hello
如果 JWT 有效,将返回:
{
"message": "Hello, authenticated user!"
}
总结
这个示例展示了如何在 Gin 框架中实现 JWT 认证,包括用户登录、生成 JWT 和验证 JWT 的中间件。你可以根据需求进行扩展,例如从数据库获取用户信息和密码验证等。