gin入门教程(10):实现jwt认证

使用 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 包:

bash 复制代码
go get github.com/golang-jwt/jwt

2. cmd/main.go

主程序,设置路由和中间件。

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

定义路由,包括登录和受保护的资源。

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 的逻辑。

go 复制代码
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 验证中间件。

go 复制代码
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. 测试应用

在项目根目录下运行:

bash 复制代码
go run cmd/main.go
登录

使用 Postman 或 cURL 发送 POST 请求到 http://localhost:8080/login,请求体示例:

json 复制代码
{
    "username": "testuser",
    "password": "testpassword"
}

如果登录成功,将返回一个 JWT:

json 复制代码
{
    "token": "your_jwt_token"
}
访问受保护的资源

使用返回的 JWT 作为 Authorization 头部的值,发送 GET 请求到 http://localhost:8080/protected/hello

bash 复制代码
curl -H "Authorization: your_jwt_token" http://localhost:8080/protected/hello

如果 JWT 有效,将返回:

json 复制代码
{
    "message": "Hello, authenticated user!"
}

总结

这个示例展示了如何在 Gin 框架中实现 JWT 认证,包括用户登录、生成 JWT 和验证 JWT 的中间件。你可以根据需求进行扩展,例如从数据库获取用户信息和密码验证等。

相关推荐
搞不懂语言的程序员6 分钟前
装饰器模式详解
开发语言·python·装饰器模式
王禄DUT11 分钟前
化学方程式配平 第33次CCF-CSP计算机软件能力认证
开发语言·c++·算法
Yang-Never12 分钟前
Open GL ES ->纹理贴图,顶点坐标和纹理坐标组合到同一个顶点缓冲对象中进行解析
android·java·开发语言·android studio·贴图
DreamByte26 分钟前
C++菜鸟教程 - 从入门到精通 第五节
开发语言·c++·算法
Ljugg38 分钟前
把doi直接插入word中,然后直接生成参考文献
开发语言·c#·word
长流小哥39 分钟前
可视化开发:用Qt实现Excel级动态柱状图
开发语言·c++·qt·ui
Python测试之道1 小时前
Deepseek API+Python 测试用例一键生成与导出 V1.0.6(加入分块策略,返回更完整可靠)
开发语言·python·测试用例
SRC_BLUE_171 小时前
Python GUI 编程 | QObject 控件基类详解 — 定时器
开发语言·数据库·python
啊阿狸不会拉杆1 小时前
第二十一章:Python-Plotly库实现数据动态可视化
开发语言·python·plotly
滴答滴答嗒嗒滴1 小时前
Python小练习系列 Vol.12:学生信息排序(sorted + key函数)
开发语言·python