开发者

golang jwt鉴权的实现流程

目录
  • 1. 用户登录
  • 2. 生成 JWT 令牌
  • 3. 返回 JWT 令牌
  • 4. 客户端存储 JWT 令牌
  • 5. 客户端发送请求
  • 6. 服务端验证 JWT 令牌
  • 7. 处理请求
  • 示例代码
    • 生成 JWT 令牌(服务端)
    • 验证 JWT 令牌(服务端)
  • 示例代码:

    JWT(jsON Web Token)是一种用于在网络应用环境间传递声明(Claims)的无状态、独立、紧凑和独立的信息格式。以下是 JWT 进行鉴权的基本流程:

    1. 用户登录

    用户通过编程用户名和密码登录系统,系统验证用户身份。

    2. 生成 JWT 令牌

    系统验证用户身份成功后,生成一个 JWT 令牌。JWT 令牌通常包含以下部分:

    • Header(头部):包含令牌的类型(通常是 JWT)和使用的签名算法(如 HMAC-SHA256)。

    • Payload(载荷):包含声明(Claims),这些声明可以是用户 ID、角色、过期时间等。

    • Signature(签名):用于验证 JWT 的完整性和真实性。

    3. 返回 JWT 令牌

    系统将生成的 JWT 令牌返回给客户端(通常是浏览器或移动应用)。

    4. 客户端存储 JWT 令牌

    客户端收到 JWT 令牌后,通常会将其存储在本地存储(如 localStorage 或 sessionStorage)或 Cookie 中。

    5. 客户端发送请求

    客户端在后续的请求中,将 JWT 令牌放在 HTTP 请求头的 Authorization 字段中,格式通常为 Bearer <token>

    6. 服务端验证 JWT 令牌

    服务端接收到请求后,从 Authorization 请求头中提取 JWT 令牌,并进行验证:

    • 验证签名:使用与生成 JWT 时相同的密钥验证 JWT 的签名是否有效。

    • 验证过期时间:检查 JWT 的过期时间是否已过。

    • 验证其他声明:根据需要验证其他声明,如用户角色、权限等。

    7. 处理请求

    如果 JWT 令牌验证通过,服务端处理请求并返回响应。如果验证失败,返回错误响应(如 401 Unauthorized)。

    示例代码

    生成 JWT 令牌(服务端)

    package main
    
    import (
        "fmt"
        "time"
        "github.com/golang-jwt/jwt"
    )
    
    // 自定义 Claims
    type CustomClaims struct {
        UserID   string `json:"user_id"`
        Role     string `json:"role"`
        jwt.StandardClaims
    }
    
    func main() {
        // 自定义 Claims
        claims := CustomClaims{
            UserID: js"12345",
            Role:   "admin",
            StandardClaims: jwt.StandardClaims{
                ExpiresAt: time.Now().Add(24 * time.Hour).Unix(),
                Issuer:    "myapp",
            },
        }
    
        // 密钥
        jwtSecret := "mysecretkey"
    
        // 创建 JWT 令牌
        token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    
        /javascript/ 使用密钥签名并生成字符串形式的 JWT 令牌
        tokenString, err := token.SignedString([]byte(jwtSecret))
        if err != nil {
            fmt.Println("生成令牌失败:", err)
            return
        }
    
        fmt.Println("生成的 JWT 令牌:", tokenString)
    }

    验证 JWT 令牌(服务端)

    package main
    
    import (
        "fmt"
        "net/http"
        "strings"
     python   "github.com/golang-jwt/jwt"
    )
    
    // 自定义 Claims
    type CustomClaims struct {
        UserID   string `json:"user_id"`
        Role     string `json:"role"`
        jwt.StandardClaims
    }
    
    func handler(w http.ResponseWriter, r *http.Request) {
        // 获取 Authorization 请求头
        authHeader := r.Header.Get("Authorization")
    
        // 检查 Authorization 请求头是否存在
        if authHeader == "" {
            http.Error(w, "Missing Authorization header", http.StatusUnauthorized)
            return
        }
    
        // 提取 JWT 令牌
        tokenString := strings.TrimPrefix(authHeader, "Bearer ")
    
        // 验证 JWT 令牌
        token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
            // 提供签名密钥
            return []byte("mysecretkey"), nil
        })
    
        if err != nil {
            http.Error(w, "Invalid token", http.StatusUnauthorized)
            return
        }
    
        if !token.Valid {
            http.Error(w, "Invalid token", http.StatusUnauthorized)
            return
        }
    
        // 处理请求
        fmt.Fprintf(w, "Hello, World!")
    }
    
    func main() {
        http.HandleFunc("/api/data", handler)
        http.ListenAndServe(":8080", nil)
    }

    可以将验证jwt令牌的方法定义为中间件(Middleware),通过Use方法注册到gin中,应用于所有路由。gin的中间件在请求处理流程中被调用,可以对请求进行预处理、修改请求或响应,甚至可以终止请求的处理。中间件在 Gin 中非常常用,可以用于实现诸如身份验证、日志记录、请求限制等功能。

    示例代码:

    package main
    
    import (
        "github.com/gin-gonic/gin"
        "github.com/golang-jwt/jwt"
        "strings"
    )
    
    // 自定义 Claims
    type CustomClaims struct {
        UserID   string `json:"user_id"`
        Role     string `json:"role"`
        jwt.StandardClaims
    }
    
    // Auth 返回一个 Gin 中间件函数
    func Auth() gin.HandlerFunc {
        return func(c *gin.Context) {
            // 获取 Authorization 请求头
            authHeader := c.GetHeader("Authorization")
    
            // 检查 Authorization 请求头是否存在
            if authHeader == "" {
                c.JSON(401, gin.H{"error": "Missing Authorization header"})
                c.Abort()
                return
            }
    
            // 提取 JWT 令牌
            tokenString := strings.TrimPrefix(authHeader, "Bearer ")
    
            // 验证 JWT 令牌
            token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
                // 提供签名密钥
                return []byte("mysecretkey"), nil
            })
    
            if err != nil {
                c.JSON(401, gin.H{"error": "Invalid token"})
                c.Abort()
                return
            }
    
            if !token.Valid {
                c.JSON(401, gin.H{"error": "Invalid token"})
                c.Abort()
                return
            }
    
            // 如果验证通过,继续处理请求
            c.Next()
        }
    }
    
    func main() {
        r := gin.Default()
    
        // 使用 Auth 中间件
        r.Use(Auth())
    
        r.GET("/api/data", func(c *gin.Context) {
            c.JSON(200, gin.H{"message": "Hello, World!"})
        })
    
        r.Run(":8080")
    }

    到此这篇关于golang jwt鉴权的实现流程的文章就介绍到这了,更多相关golang jwt鉴权内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.cppcnspython.com)! 

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜