耶耶耶耶耶 发表于 2025-1-16 23:08:41

【gin】中间件使用之jwt身份认证和Cors跨域,go案例

Gin-3 中间件编程及 JWT 身份认证

1. Gin 中间件概述

中间件是处置惩罚 HTTP 请求的函数,可以在请求到达路由处置惩罚函数之前或之后对请求进行处置惩罚。
在 Gin 框架中,中间件常用于处置惩罚日志记录、身份验证、权限控制等功能。
router := gin.Default()
router.Use(middleware) // 使用中间件
中间件可以通过 Use 方法进行添加,并且可以用于全部路由或特定路由组。
2. JWT 简介

https://github.com/golang-jwt/jwt
JSON Web Token(JWT)是一种用于认证和授权的标准。JWT 包罗三个部分:

[*]头部 (Header)
[*]载荷 (Payload)
[*]署名 (Signature)
JWT = Base64UrlEncode(HEADER) + "." + Base64UrlEncode(PAYLOAD) + "." + Base64UrlEncode(SIGNATURE)
JWT 的优点是自包罗,它在用户和服务之间转达信息时不依赖于存储。
由于 JWT 包罗全部须要的用户信息,服务端不需要保持用户的状态。
3. Gin 中的 JWT 身份认证明现

在 Gin 中实现 JWT 身份认证主要包罗以下步骤:

[*]天生 JWT Token:登录时天生 JWT Token。
[*]验证 JWT Token:通过中间件验证请求中的 Token。
[*]访问受掩护路由:只有验证通过的用户才华访问受掩护的路由。
3.1 JWT 天生与验证函数

通过以下代码,您可以天生和验证 JWT Token:
package jwt_plugin

import "github.com/golang-jwt/jwt/v5"

var key = "abcdefg123" // 用于加密和解密的密钥

// 数据结构,存储用户信息和标准声明
type Data struct {
    Name   string `json:"name"`
    Age    int    `json:"age"`
    Gender int    `json:"gender"`
    jwt.RegisteredClaims
}

// 生成 JWT Token
func Sign(data jwt.Claims) (string, error) {
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, data)
    sign, err := token.SignedString([]byte(key))
    if err != nil {
      return "", err
    }
    return sign, nil
}

// 验证 JWT Token
func Verify(sign string, data jwt.Claims) error {
    _, err := jwt.ParseWithClaims(sign, data, func(token *jwt.Token) (any, error) {
      return []byte(key), nil
    })
    return err
}
天生 JWT Token 时,我们会使用 Sign 函数,验证时使用 Verify 函数。
Sign 函数会将用户信息(载荷)和署名一起返回,Verify 函数用于验证 JWT Token 是否有效。
3.2 登录接口实现

用户登录时,通过 Login 函数天生 JWT Token,并返回给客户端。
package login

import (
    "github.com/gin-gonic/gin"
    "golang13-gin/jwt_plugin"
    "net/http"
    "time"
)

func Login(c *gin.Context) {
    // 用户信息及 JWT 载荷
    data := jwt_plugin.Data{
      Name:   "nick",
      Age:    18,
      Gender: 1,
      RegisteredClaims: jwt.RegisteredClaims{
            ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour)),
            IssuedAt:jwt.NewNumericDate(time.Now()),
            NotBefore: jwt.NewNumericDate(time.Now()),
      },
    }
   
    // 生成 JWT Token
    sign, err := jwt_plugin.Sign(data)
    if err != nil {
      c.JSON(http.StatusInternalServerError, gin.H{
            "error": err.Error(),
      })
      return
    }

    // 返回 JWT Token
    c.JSON(http.StatusOK, gin.H{
      "access_token": sign,
    })
}
登录成功后,系统会返回一个包罗用户信息和有效期的 JWT Token。
3.3 JWT 身份验证中间件

package middleware

import (
    "github.com/gin-gonic/gin"
    "golang13-gin/jwt_plugin"
    "net/http"
)

func Auth() gin.HandlerFunc {
    return func(c *gin.Context) {
      accessToken := c.Request.Header.Get("access_token") // 获取请求头中的 Token
      data := &jwt_plugin.Data{}
      err := jwt_plugin.Verify(accessToken, data) // 验证 Token
      if err != nil {
            c.JSON(http.StatusForbidden, gin.H{
                "error": "身份认证失败",
            })
            c.Abort() // 中止请求
      }
      c.Set("auth_info", data) // 将用户信息存储在上下文中
      c.Next() // 继续后续处理
    }
}
身份验证中间件 Auth 会从请求头中提取 JWT Token 并进行验证。假如验证失败,返回 403 错误;否则将用户信息存储到上下文,供后续路由使用。
4. CORS 中间件

CORS(跨域资源共享)答应服务器指定哪些源(Origin)可以访问资源。以下是设置 CORS 中间件的代码:
package middleware

import (
    "github.com/gin-contrib/cors"
    "github.com/gin-gonic/gin"
)

func Cors() gin.HandlerFunc {
    return cors.New(cors.Config{
      AllowAllOrigins: true,
      AllowHeaders: []string{
            "Origin", "Content-Length", "Content-Type",
      },
      AllowMethods: []string{
            "GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS",
      },
    })
}
CORS 中间件配置答应来自任何来源的请求,并且可以处置惩罚指定的 HTTP 方法和头部。
5. 路由初始化与中间件使用

在 Gin 中,可以通过 Use 方法将中间件添加到路由组中,以下是一个例子:
func InitRoutes(r *gin.Engine) {   
    api := r.Group("/api")   
    api.Use(middleware.Cors(), middleware.Auth()) // 使用 CORS 和 JWT 验证中间件



    InitCourse(api)   
    InitUser(api)   
    InitUpload(api)   

    notAuthApi := r.Group("/api")   
    notAuthApi.Use(middleware.Cors())   
    InitLogin(notAuthApi) // 不需要身份验证的路由   
}
总结

概念形貌代码示例Gin 中间件中间件是一个函数,用来处置惩罚 HTTP 请求。在请求进入路由处置惩罚函数之前或之后,实行某些操纵。router.Use(middleware)JWT (JSON Web Token)一种用于认证和授权的标准格式,通过三个部分构成:头部、载荷和署名。它具有自包罗特性,可以在分布式系统中使用。token := jwt.NewWithClaims(jwt.SigningMethodHS256, data)JWT 天生通过载荷和密钥天生 JWT Token。sign, err := jwt_plugin.Sign(data)JWT 验证通过 Token 验证用户身份,确保请求的合法性。err := jwt_plugin.Verify(accessToken, data)身份认证中间件在请求到达目的路由之前,验证请求中的 JWT Token,确保只有通过验证的请求才华继续处置惩罚。func Auth() gin.HandlerFunc { return func(c *gin.Context) { ... } }CORS 中间件办理欣赏器跨域问题,答应差别域的请求访问服务器资源。func Cors() gin.HandlerFunc { return cors.New(cors.Config{ AllowAllOrigins: true }) }路由组将具有共同前缀的路由放在一个组中,方便统一管理和中间件的应用。api := r.Group("/api")JWT 载荷JWT 中的数据部分,包罗用户信息和其他元数据。可以自界说内容,也可以使用预界说的注册声明(如过期时间)。RegisteredClaims: jwt.RegisteredClaims{ ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour)) }路由配置界说与中间件、请求处置惩罚函数相关的路由。InitLogin(notAuthApi) 表格表明:

[*]Gin 中间件 是一类用于在路由处置惩罚函数实行前或后处置惩罚请求的函数,常见的中间件包罗身份认证、中间件控制等。
[*]JWT 是一种 JSON 格式的认证方式,包罗头部、载荷和署名,实用于分布式系统,办理了服务端无状态的问题。
[*]JWT 天生和验证 是通过特定的密钥和载荷数据天生的,可以通过库函数轻松实现天生和验证操纵。
[*]身份认证中间件 通过在请求处置惩罚中拦截请求并验证 JWT Token 是否有效来确保用户身份的合法性。
[*]CORS 中间件 答应差别来源的客户端发起请求,办理跨域问题,常见于前后端分离的应用场景。
[*]路由组 可以帮助组织和管理具有共同特性的路由,通过给路由组添加中间件,使得多个路由共享特定的功能。
[*]JWT 载荷 中的数据部分,存储的是用户信息以及与身份认证相关的信息(如过期时间等)。
JWT载荷

JWT 载荷部分是什么,是否无关紧急?
JWT 的载荷部分是存储在 Token 中的实际信息,它包罗了 声明(claims),这些声明通常用于存储用户信息、权限、Token 的有效期等。
JWT 载荷部分包罗以下几种范例的声明:


[*]注册声明(Registered Claims):如 exp(过期时间)、iat(签发时间)、sub(主题)等。
[*]公共声明(Public Claims):可以自界说,用于表示用户信息或其他数据。
[*]私有声明(Private Claims):由双方约定用于转达的信息。
是否无关紧急?
假如只是需要转达一个简单的标识符(如用户 ID),那么可以简化载荷部分。
但通常,JWT 的载荷是不可或缺的,因为它包罗了 Token 的有效期、权限等紧张信息。
假如载荷部分为空或缺少须要的字段,Token 的使用代价将大大低落。
https://github.com/0voice

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【gin】中间件使用之jwt身份认证和Cors跨域,go案例