【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 包含三个部分:

  1. 头部 (Header)
  2. 载荷 (Payload)
  3. 签名 (Signature)
JWT = Base64UrlEncode(HEADER) + "." + Base64UrlEncode(PAYLOAD) + "." + Base64UrlEncode(SIGNATURE)

JWT 的优点是自包含,它在用户和服务之间传递信息时不依赖于存储。
由于 JWT 包含所有必要的用户信息,服务端不需要保持用户的状态。

3. Gin 中的 JWT 身份认证实现

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

  1. 生成 JWT Token:登录时生成 JWT Token。
  2. 验证 JWT Token:通过中间件验证请求中的 Token。
  3. 访问受保护路由:只有验证通过的用户才能访问受保护的路由。

3.1 JWT 生成与验证函数

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

package jwt_pluginimport "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 loginimport ("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 Tokensign, err := jwt_plugin.Sign(data)if err != nil {c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error(),})return}// 返回 JWT Tokenc.JSON(http.StatusOK, gin.H{"access_token": sign,})
}

登录成功后,系统会返回一个包含用户信息和有效期的 JWT Token。

3.3 JWT 身份验证中间件

package middlewareimport ("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") // 获取请求头中的 Tokendata := &jwt_plugin.Data{}err := jwt_plugin.Verify(accessToken, data) // 验证 Tokenif 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 middlewareimport ("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)

表格解释:

  1. Gin 中间件 是一类用于在路由处理函数执行前或后处理请求的函数,常见的中间件包括身份认证、中间件控制等。
  2. JWT 是一种 JSON 格式的认证方式,包含头部、载荷和签名,适用于分布式系统,解决了服务端无状态的问题。
  3. JWT 生成和验证 是通过特定的密钥和载荷数据生成的,可以通过库函数轻松实现生成和验证操作。
  4. 身份认证中间件 通过在请求处理中拦截请求并验证 JWT Token 是否有效来确保用户身份的合法性。
  5. CORS 中间件 允许不同来源的客户端发起请求,解决跨域问题,常见于前后端分离的应用场景。
  6. 路由组 可以帮助组织和管理具有共同特征的路由,通过给路由组添加中间件,使得多个路由共享特定的功能。
  7. 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/2586.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SDK调用文心一言如何接入,文心一言API接入教程

一、前期准备 注册百度智能云账号: 前往百度智能云官网注册一个账号。这是接入文心一言API的基础。 了解API接口: 在百度智能云开放平台中,找到文心一言API的详情页,了解提供的API接口类型(如云端API、移动端API、离线…

linux之进程信号(初识信号,信号的产生)

目录 引入一、初识信号(信号预备知识)1.生活中的信号2.Linux中的信号3.信号进程得出的初步结论 二、信号的产生1.通过终端输入产生信号拓展: 硬件中断2.调用系统函数向进程发信号3.硬件异常产生信号4.软件条件产生信号拓展: 核心转储技术总结一下: 引入 一、初识信…

​​​​​​​​​​​​​​★3.3 事件处理

★3.3.1 ※MouseArea Item <-- MouseArea 属性 acceptedButtons : Qt::MouseButtons containsMouse : bool 【书】只读属性。表明当前鼠标光标是否在MouseArea上&#xff0c;默认只有鼠标的一个按钮处于按下状态时才可以被检测到。 containsPress : bool curs…

从前端视角看设计模式之创建型模式篇

设计模式简介 "设计模式"源于GOF&#xff08;四人帮&#xff09;合著出版的《设计模式&#xff1a;可复用的面向对象软件元素》&#xff0c;该书第一次完整科普了软件开发中设计模式的概念&#xff0c;他们提出的设计模式主要是基于以下的面向对象设计原则&#xff…

DAMA CDGA 备考笔记(二)

1. 考点分布 2. 第二章 数据处理伦理知识点总结 伦理是建立在是非观念上的行为准则。伦理准则通常侧重于公平、尊重、责任、诚信、质量、可靠性、透明度和信任等方面。数据伦理是一项社会责任问题不是法律问题。 度量指标&#xff1a;培训员工人数、合规/不合规事件、企业高管…

ros2笔记-6.2 使用urdf创建机器人模型

本节主要跟着小鱼老师的视频操作&#xff0c;不同的仿真平台有不同的建模语言&#xff0c;但是几乎都支持URDF。 本节使用URDF创建一个机器人模型。 6.2.1 帮机器人创建一个身体 URDF使用XML来描述机器人的结构和传感器、执行器等信息。 在chapt6/chap6_ws/src创建功能包:r…

MLX90640自制热像仪(四) LVGL UI界面设计 移植 SquareLine Studio

SquareLine Studio 1.5.0是一款LVGL图形化的软件&#xff0c;LVGL官方的软件&#xff0c;针对这个软件我们主要做的除了开发&#xff0c;就是移植到自己的板端&#xff0c;过程中会遇到各种各样的问题。 下面附上源代码&#xff1a; // This file was generated by SquareLine…

hadoop3.3和hive4.0安装——单节点

hadoop3.3x和hive4.0安装部署 为什么我要安装hive4.0&#xff0c;因为阿里云镜像只有hive4.0 软件相互兼容性版本 系统centos7 uname -a如果内核3.0以上可以用 安装jdk1.8以上的版本&#xff08;配置好环境变量&#xff09; hadoop3.3.x与hive4.0.x 创建目录 mkdir -p /us…

09.VSCODE:安装 Git for Windows

在 Windows 下安装著名的源代码管理工具&#xff1a;git。 git 工具两大作用&#xff1a; 管理我们自己的源代码获取他人&#xff08;开源的&#xff09;源代码 当前我们更需要第2点。 为什么要安装 git 一、 得到更多库 之前课程中我们安装了 msys2&#xff0c;从而可以通…

《银行保险机构数据安全管理办法》正式实施,分类分级、安全评估共筑安全防线

金融数据具有高价值和高敏感性&#xff0c;金融数据安全关乎国家安全和金融消费者权益密切相关。在当前数字化进程加速的背景下&#xff0c;数据合作频繁&#xff0c;安全风险也随之增加&#xff0c;给机构管理带来了新挑战。 为规范银行业保险业数据处理活动&#xff0c;保障数…

CV(10)--目标检测

前言 仅记录学习过程&#xff0c;有问题欢迎讨论 目标检测 object detection&#xff0c;就是在给定的图片中精确找到物体所在位置&#xff0c;并标注出物体的类别;输出的是分类类别label物体的外框&#xff08;x, y, width, height&#xff09;。 目标检测算法&#xff1a…

Nginx 如何设置 Upgrade-Insecure-Requests 报头 ?

Upgrade-Insecure-Requests 报头是一种 web 浏览器向服务器发出信号的机制&#xff0c;它倾向于接收安全 (HTTPS) 资源。添加此报头有助于在受支持的浏览器上将不安全的请求升级为安全的请求。 Step 1: 定位 Nginx 配置 主 nginx 配置文件通常位于 /etc/nginx/nginx.conf特定…

3.Qt Quick-QML地图引擎之v4.3版本(新增动态轨迹线/海图/天地图街道/天地图卫星)

在上个版本Qt Quick-QML地图引擎之v4版本(新增多模型切换/3D模型欧拉角模拟)_qt加载3d地图-CSDN博客更新了3D模拟功能&#xff0c;在4.3版本增加动态轨迹线、三个地图(海图/天地图街道/天地图卫星)。 4.3版本已经支持qt6 cmake版本&#xff0c;而4.3版本以下支持qt5版本&#x…

Linux-----线程操作(创建)

目录 创建线程 示例&#xff1a; 创建线程 #include <pthread.h>/*** 创建一个新线程* * pthread_t *thread: 指向线程标识符的指针,线程创建成功时,用于存储新创建线程的线程标识符* const pthread_attr_t *attr: pthead_attr_t结构体,这个参数可以用来设置线程的属性…

我要成为算法高手-DFS篇

目录 题目1&#xff1a;计算布尔二叉树的值题目2&#xff1a;求根节点到叶子结点数字之和题目3&#xff1a;二叉树剪枝题目4&#xff1a;验证二叉搜索树题目4&#xff1a;二叉搜索树中第 K 小的元素题目5&#xff1a;二叉树的所有路径 题目1&#xff1a;计算布尔二叉树的值 23…

学习threejs,使用FlyControls相机控制器

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.FlyControls 相机控制…

Life Long Learning(李宏毅)机器学习 2023 Spring HW14 (Boss Baseline)

1. 终身学习简介 神经网络的典型应用场景是,我们有一个固定的数据集,在其上训练并获得模型参数,然后将模型应用于特定任务而无需进一步更改模型参数。 然而,在许多实际工程应用中,常见的情况是系统可以不断地获取新数据,例如 Web 应用程序中的新用户数据或自动驾驶中的…

Multi-Agent如何设计

文章小结 研究背景和目的 在单一大语言模型长期主导人工智能领域的背景下&#xff0c;多智能体系统在对话任务解决中逐渐崭露头角。 虽然先前的研究已经展示了多智能体系统在推理任务和创造性工作中的潜力&#xff0c;但对于其在对话范式方面的局限性以及单个智能体的影响&am…

(即插即用模块-Attention部分) 四十四、(ICIP 2022) HWA 半小波注意力

文章目录 1、Half Wavelet Attention2、代码实现 paper&#xff1a;HALFWAVELET ATTENTION ON M-NET FOR LOW-LIGHT IMAGE ENHANCEMENT Code&#xff1a;https://github.com/FanChiMao/HWMNet 1、Half Wavelet Attention 传统的图像增强方法主要关注图像在空间域的特征信息&am…

SpringBoot+Lombok项目实体属性名xXxx格式,前端接收不到

问题解析 今天发现后端传给前端的实体类中&#xff0c;有属性为xXxxx格式的&#xff0c;前端也使用相同名称接收&#xff0c;结果却不显示值&#xff01;研究了一会发现接口请求回来后&#xff0c;原xXxxx的属性名&#xff0c;会被转为全小写。具体原因为&#xff1a;使用Lombo…