马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
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企服之家,中国第一个企服评测及商务社交产业平台。 |