【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_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) |
表格解释:
- 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
相关文章:
【gin】中间件使用之jwt身份认证和Cors跨域,go案例
Gin-3 中间件编程及 JWT 身份认证 1. Gin 中间件概述 中间件是处理 HTTP 请求的函数,可以在请求到达路由处理函数之前或之后对请求进行处理。 在 Gin 框架中,中间件常用于处理日志记录、身份验证、权限控制等功能。 router : gin.Default() router.Us…...
【JAVA实战】@FeignClient注解类通用请求封装
背景 最近在编写多个系统数据集成过程中,经常会使用到FeignClient注解标记一个类,类里面编写很多请求方法,如果第三方系统有非常多的URL请求,每个方法对应一个URL请求,那么这个类就会非常的庞大,是否有一种…...

[c语言日寄]精英怪:三子棋(tic-tac-toe)3命慢通[附免费源码]
哈喽盆友们,今天带来《c语言》游戏中[三子棋boss]速通教程!我们的目标是一边编写博文,一边快速用c语言实现三子棋游戏。准备好瓜子,我们计时开始! 前期规划 在速通中,我们必须要有清晰的前期规划…...
GORM(Go语言数据交互库)
GORM(Go ORM,即对象关系映射)是Go语言中非常流行且功能强大的数据库交互库。它简化了与关系型数据库的交互过程,提供了丰富的API来处理各种数据库操作。下面将详细介绍GORM的功能、使用方法和一些高级特性。 1. 安装 首先&#…...
Redis主从同步是怎么实现的?
Redis主从同步是怎么实现的? 主从节点建立连接后,从节点会进行判断: 1.如果这是从节点之前没有同步过数据 属于初次复制,会进行全量重同步,那么从节点会向主节点发送PSYNC?-1 命令,请求主节点进行全量重…...

Flutter中Get.snackbar避免重复显示的实现
在pubspec.yaml中引入依赖框架。 #GetX依赖注解get: ^4.6.5创建一个SnackBarManager管理类去管理每个提示框。 import package:get/get.dart; import package:flutter/material.dart;class SnackBarManager {factory SnackBarManager() > instance;static final SnackBarMa…...

[Qt]常用控件介绍-多元素控件-QListWidget、QTableWidget、QQTreeWidget
目录 1.多元素控件介绍 2.ListWidget控件 属性 核心方法 核心信号 细节 Demo:编辑日程 3.TableWidget控件 核心方法 QTableWidgetItem核心信号 QTableWidgetItem核心方法 细节 Demo:编辑学生信息 4.TreeWidget控件 核心方法 核心信号…...

深入Android架构(从线程到AIDL)_32 JNI架构原理_Java与C的对接05
1、EIT造形观点 基于熟悉的EIT造形,很容易理解重要的架构设计决策议题。 前言 2、混合式EIT造形 一般EIT造形是同语言的。也就是<E>、 <I>和<T>都使用同一种语言撰写的,例如上述的Java、 C/C等。于此,将介绍一个EIT造…...
【gRPC】clientPool 客户端连接池简单实现与go案例
什么是 gRPC 客户端连接池? 在 gRPC 中,创建和维护一个到服务器的连接是非常消耗资源的(比如 TCP 连接建立和 TLS 握手)。 而在高并发场景下,如果每次请求都创建新的连接,不仅会导致性能下降,还…...

Android 15应用适配指南:所有应用的行为变更
Android系统版本适配,一直是影响App上架Google Play非常重要的因素。 当前Google Play政策规定 新应用和应用更新 必须以 Android 14(API 级别 34)为目标平台,才能提交到Google Play。现有应用 必须以 Android 13(AP…...

24-25-1-单片机开卷部分习题和评分标准
依据相关规定试卷必须按评分标准进行批改。 给分一定是宽松的,能给分一定给,如有疑问也可以向学院教务办申请查卷。 一部分学生期末成绩由于紧张或其他原因导致分数过低,也是非常非常遗憾的。 个人也是非常抱歉的。 开卷考试 简答题 第一…...

STM32第6章、WWDG
一、简介 WWDG:全称Window watchdog,即窗口看门狗,本质上是一个能产生系统复位信号和提前唤醒中断的计数器。 特性: 是一个递减计数器。 看门狗被激活后, 当递减计数器值从 0x40减到0x3F时会产生复位(即T6位…...

汽车免拆诊断案例 | 2007 款法拉利 599 GTB 车发动机故障灯异常点亮
故障现象 一辆2007款法拉利599 GTB车,搭载6.0 L V12自然吸气发动机(图1),累计行驶里程约为6万km。该车因发动机故障灯异常点亮进厂检修。 图1 发动机的布置 故障诊断 接车后试车,发动机怠速轻微抖动,…...

C语言-数据结构-队列
目录 1.队列的特点 2.队列的实现 2.1.初始化队列 2.2.入队列 2.2.1.入空队列 2.2.2.入非空队列 2.3.出队列 2.4.销毁队列 2.5.完整代码 3.实际应用 1.队列的特点 队列是一种常见的数据结构,它遵循先进先出(FIFO, First In First Out)…...

STL之VectorMapList针对erase方法踩坑笔记
前沿 如下总结的三种容器,开头都会涉及当前容器的特点,再者就本次针对erase方法的使用避坑总结。 一.Vector vector关联关联容器,存储内存是连续,且特点支持快速访问,但是插入和删除效率比较地(需要找查找和移动)。另…...

梯度下降法为什么要提前停止
什么是提前停止(Early Stopping)? 提前停止是一种正则化技术,用于在训练机器学习模型(特别是神经网络)时防止过拟合。它的核心思想是通过监控模型在验证集上的性能,在性能开始恶化之前停止训练…...

【vue3项目使用 animate动画效果】
vue3项目使用 animate动画效果 前言一、下载或安装npm 安装 二、引入组件三、复制使用四、完整使用演示总结 前言 提示:干货篇,不废话,点赞收藏,用到会后好找藕~ 点击这里,直接看官网哦 👉 官网地址&#…...
1.1.1 C语言常用的一些函数(持续更新)
总框架见(0. 总框架-CSDN博客) (1)socket (a)分配fd;(b)分配tcp控制块(tcb) int socket(int domain, int type, int protocol);AF_INET IPv4 Internet protocols ip(7)AF_INET6 IP…...

李宏毅机器学习课程笔记03 | 类神经网络优化技巧
文章目录 类神经网络优化技巧局部最小值local minima 与 鞍点saddle pointSaddle Point 的情况更常见 Tips for training:Batch and MomentumSmall Batch vs Large Batch回顾:optimization优化 找到参数使L最小问题:为什么要用Batchÿ…...
简洁明快git入门及github实践教程
简洁明快git入门及github快速入门实践教程 前言git知识概要:一:什么是 Git?二:安装 Git三:配置 Git配置git的用户名和邮箱地址创建仓库 四:Git实践五:远程仓库操作(基于git命令使用G…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...

LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...

PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...