如何在go里使用jwt(包含示例)

news2025/1/12 15:53:39

什么是JWT

JWT就是一种基于Token的轻量级认证模式,服务端认证通过后,会生成一个JSON对象,经过签名后得到一个Token(令牌)再发回给用户,用户后续请求只需要带上这个Token,服务端解密之后就能获取该用户的相关信息了。

版本信息

go:1.22.3
github.com/golang-jwt/jwt/v5 v5.2.1
github.com/jinzhu/gorm v1.9.16
开启了mod模式

使用示例

创建vue目录,go mod init vue,创建midware文件夹,下面创建文件jwt.go,内容如下:

package midware

import (
	"errors"
	"net/http"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v5"
)

// CustomClaims 自定义声明类型 并内嵌jwt.RegisteredClaims
// jwt包自带的jwt.RegisteredClaims只包含了官方字段
// 假设我们这里需要额外记录一个username字段,所以要自定义结构体
// 如果想要保存更多信息,都可以添加到这个结构体中
type CustomClaims struct {
	// 可根据需要自行添加字段
	Username string `json:"username"`
	Password string `json:"password"`
	jwt.RegisteredClaims        // 内嵌标准的声明
}

var CustomSecret = []byte("djsahkdasduowjbnckauwna")
 
// GenToken 生成JWT
func GenToken(password, username string) (string, error) {
	// 创建一个我们自己声明的数据
	claims := CustomClaims{
		password,
		username, // 自定义字段
		jwt.RegisteredClaims{
			ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * 24)),	// 定义过期时间
			Issuer:    "somebody", // 签发人
		},
	}
	
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	// 生成签名字符串
	return token.SignedString(CustomSecret)
}

func ParseToken(tokenString string) (*CustomClaims, error) {
	// 解析token
	var mc = new(CustomClaims)
	token, err := jwt.ParseWithClaims(tokenString, mc, func(token *jwt.Token) (i interface{}, err error) {
		return CustomSecret, nil
	})
	if err != nil {
		return nil, err
	}
	// 对token对象中的Claim进行类型断言
	if token.Valid { // 校验token
		return mc, nil
	}
	return nil, errors.New("invalid token")
}

func JWTAuthMiddleware() func(c *gin.Context) {
	return func(c *gin.Context) {
		//获取到请求头中的token
		authHeader := c.Request.Header.Get("Authorization")
		if authHeader == "" {
			c.JSON(http.StatusOK, gin.H{
				"Msg":  "请求头中的auth为空!",
				"Data": nil,
			})
			c.Abort()
			return
		}
		// 按空格分割
		parts := strings.SplitN(authHeader, " ", 2)
		if !(len(parts) == 2 && parts[0] == "Bearer") {
			c.JSON(http.StatusOK, gin.H{
				"Msg":  "请求头中的auth格式错误",
				"Data": nil,
			})
			c.Abort()
			return
		}
		// parts[1]是获取到的tokenString,我们使用之前定义好的解析JWT的函数来解析它
		mc, err := ParseToken(parts[1])
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"Msg":  "访问失败,无效的token,请登录!",
				"Data": nil,
			})
			c.Abort()
			return
		}
		// 将当前请求的userID信息保存到请求的上下文c上
		c.Set("Username", mc.Username)
		c.Next() // 后续的处理函数可以用过c.Get("username")来获取当前请求的用户信息
	}
}

然后在vue目录下创建main.go,如下

package main

import (
	"fmt"
	"time"
	"vue/midware"  //导入jwt中间件

	gincors "github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
	gorm "github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)
type UserInfo struct {
	gorm.Model
	User string
	Email string
}

func main() {
	router := gin.Default()
	// 设置跨域 CORS 中间件
	router.Use(gincors.New(gincors.Config{
		AllowAllOrigins:  true, // 允许所有源
		AllowMethods:     []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
		AllowHeaders:     []string{"Origin", "Content-Length", "Content-Type", "Authorization"},
		ExposeHeaders:    []string{"Content-Length"},
		AllowCredentials: true,
		MaxAge:           12 * time.Hour,
	}))

	// 设置登录路由
	router.POST("/login", loginHandler)
	// submit添加中间件验证,这种方式中间件添加方式,中间件要放到Headler函数的前面
	router.POST("/submit", midware.JWTAuthMiddleware(), submitHeadler)
	router.Run(":8080")
}
// loginHandler 处理登录请求
func loginHandler(c *gin.Context) {
	var loginData struct {
		Username string `json:"username"`
		Password string `json:"password"`
	}
	// 从请求体中绑定 JSON 数据
	if err := c.ShouldBindJSON(&loginData); err != nil {
		c.JSON(400, gin.H{"success": false, "message": "Invalid request payload"})
		return
	}
	// 检查用户名和密码。测试方便先这样写,可以放到数据库里查询对比
	if loginData.Username == "admin" && loginData.Password == "secret" {
		token, err := midware.GenToken(loginData.Password, loginData.Username)
		if err != nil {
			c.JSON(200, gin.H{"success": true, "message": "Gen Token error", "token": token})
		}else {
			c.JSON(200, gin.H{"success": true, "message": "Login successful.", "token": token})
		}
	} else {
		c.JSON(401, gin.H{"success": false, "message": "Invalid username or password."})
	}
}
// 通过接受到的数据写到后端数据库里
func submitHeadler(c *gin.Context) {
	fmt.Println("----提交请求----")
	var submitData struct {
		Name string `json:"name"`
		Email string `json:"email"`
	}
	// 从请求体中绑定 JSON 数据
	if err := c.ShouldBindJSON(&submitData); err != nil {
		c.JSON(400, gin.H{"success": false, "message": "Invalid request payload"})
		return
	}
	name := submitData.Name
	email := submitData.Email
	// 链接数据库
	db, err := gorm.Open("mysql", "root:root@tcp(10.204.121.68:3306)/app?charset=utf8mb4&parseTime=True&loc=Local")
	if err != nil {
		panic("failed to connect database")
	}
	defer db.Close()
	db.AutoMigrate(&UserInfo{})
	db.Create(&UserInfo{
		User: name,
		Email: email,
	})
}

运行效果测试

1、运行main.go,先通过login获取token,如下图
login api
2、把上一步获取的token放到Headers里,如下图,要记得加上Bearer,格式是Bearer token
header设置:
submit api
body设置:
在这里插入图片描述
3、点击Send后,可以到数据库查看是否已写入。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于安装yarn后pnpm无法使用的问题

踩坑经过 因为公司项目变更需要,需要切换到yarn包管理工具,师父帮我调整了node版本,然后全局安装了yarn:npm install -g yarn 然后在项目里面用了yarn install然后用yarn dev语句跑起来了新项目。但是现在老项目有bug&#xff0c…

基于JSP、java、Tomcat三者的项目实战--校园交易网(2)登录,注册功能实现

技术支持:JAVA、JSP 服务器:TOMCAT 7.0.86 编程软件:IntelliJ IDEA 2021.1.3 x64 OK,那我们进入正题,随着前面一篇博客的尚未完结基于JSP、java、Tomcat三者的项目实战--校园交易网(2)登录功能…

2024杭电多校(4)1012. 寻找宝藏 【扫描线、树状数组二维偏序】

寻找宝藏 题意 思路 如果没有矩形陷阱区域的话&#xff0c;设 f i f_i fi​ 表示从 ( 0 , 0 ) (0, 0) (0,0) 到 ( i , p i ) (i, p_i) (i,pi​) 的最大收益&#xff0c;那么可以很容易通过扫描线 d p dp dp 求出&#xff1a; f i v i max ⁡ j < i ∧ p j < p …

颜色识别基于高斯混合模型(GMM)的查找表分类器(LUT)

文章目录 create_class_gmm 创建高斯混合模型&#xff08;GMM&#xff09;以进行分类任务add_samples_image_class_gmm 提取训练样本&#xff0c;并将其添加到高斯混合模型 (GMM) 的训练数据集中train_class_gmm 训练一个高斯混合模型 (GMM)clear_class_gmm 清除模型create_cla…

车载客流统计大揭秘——双目客流统计

客流统计大揭秘——双目客流统计 随着科技的飞速发展和商业竞争的加剧&#xff0c;客流统计已成为商业运营中不可或缺的一环。在众多客流统计技术中&#xff0c;双目客流统计以其高精度和高效率逐渐受到广大商家的青睐。本文将带您一探双目客流统计的奥秘。 一、什么是双目客流…

axure10的安装与使用教程,问题整理

前言&#xff1a; axure10的安装与激活使用教程。 1、百度网盘下载相关资料 链接&#xff1a;https://pan.baidu.com/s/1OSD9J1wVuIptGxeRzwjlpA?pwddkbj 提取码&#xff1a;dkbj 2、开始安装&#xff0c;点击setup的安装包 除了更改地址外&#xff0c;其他的默认就行&…

平台总线驱动和设备的匹配流程分析

参考文章:https://blog.csdn.net/qq_44182115/article/details/123231576 1、宏module_platform_driver // include/linux/platform_device.h 展开为 static int __init __platform_driver_init(void) \ {\return platform_driver_register(&

谷粒商城实战笔记-84-商品服务-API-新增商品-获取分类关联的品牌

文章目录 一&#xff0c;品牌查询接口的后台实现二&#xff0c;编码经验总结1&#xff0c;Controller层的作用1.1 参数处理1.2 调用Service1.3 处理Service返回结果实例 2&#xff0c;VO的封装时机3&#xff0c;Service中最好注入Service&#xff0c;不要直接依赖Dao 问题记录 …

BUGKU-CTF-WEB 源代码

URL解码平台&#xff1a;https://www.iamwawa.cn/urldecode.html 看看源码 存在script&#xff1a; <script> var p1 %66%75%6e%63%74%69%6f%6e%20%63%68%65%63%6b%53%75%62%6d%69%74%28%29%7b%76%61%72%20%61%3d%64%6f%63%75%6d%65%6e%74%2e%67%65%74%45%6c%65%6d%65…

基于Gunicorn、Flask和Docker的高并发应用部署指南

一、简介 随着互联网的发展&#xff0c;现代应用程序需要处理越来越多的并发请求&#xff0c;高并发应用程序的需求促使开发者寻找可靠且高效的解决方案来管理和优化服务器负载。在这种背景下&#xff0c;Gunicorn、Flask和Docker成为构建和部署高并发应用的理想组合。 首先&…

一分钟了解VMware虚拟机三种网络模式区别

VMware虚拟机提供了三种主要的网络模式&#xff0c;分别是桥接模式&#xff08;Bridged Mode&#xff09;、网络地址转换模式&#xff08;NAT Mode&#xff09;和仅主机模式&#xff08;Host-Only Mode&#xff09;。这三种模式各有其特点和适用场景&#xff0c;以下是对它们之…

mysql的回表查询

大家好&#xff0c;我是程序媛雪儿&#xff0c;今天咱们聊mysql的回表查询&#xff0c;在mysql慢查询那篇文章中我们知道&#xff0c;当extra那一列显示&#xff0c;Using index condition&#xff0c;表示直接使用了索引&#xff0c;但是需要回表查询数据&#xff0c;这种情况…

GaussDB关键技术原理|高可用:逻辑复制

GaussDB关键技术原理|高可用&#xff1a;DCF&双集群容灾从DCF与双集群容灾技术两方面对GaussDB的高可用能力进行了介绍&#xff0c;本篇将从逻辑复制方面继续解读GaussDB高可用能力。 目录 3 逻辑复制 3.1 基本概念 3.2 逻辑解码 3.3 备机解码 3.4 并行解码 3.5 一致…

docker中使用nginx配置https访问

1.申请ssl证书: https://www.joyssl.com/certificate/select/free.html 免费的ssl证书&#xff08;一般有效期是90天&#xff09;到期后&#xff0c;则需要重新申请 申请完之后下载证书 然后到验证信息中 然后到自己的域名控制台 添加解析记录(这是ssl相关的,后面还要添加自…

电测量数据交换DLMSCOSEM组件第53部分:DLMSCOSEM应用层(上)

1.范围 本部分规定了DLMS/COSEM客户机和服务器的DLMS/COSEM应用层的结构、服务和协议。同时,定义规则规定DLMS/COSEM通信配置。 它定义了用于建立和释放应用程序连接的服务,以及用于访问GB/T17215.662中使用逻辑名称(LN)或短名称(SN)引用定义的COSEM接口对象的方法和属性…

Django实战:开启数字化任务管理的新纪元

&#x1f680; Django实战&#xff1a;开启数字化任务管理的新纪元 &#x1f310; &#x1f4d6; 引言 在数字化转型的浪潮中&#xff0c;任务管理的智能化成为提升组织效能的关键。今天&#xff0c;我将带领大家深入了解我们最新开发的OFTS系统——一款创新的组织任务管理软…

【算法刷题日志】信封嵌套问题

俄罗斯套娃信封问题 信封嵌套问题可以转换为最长递增子序列的问题。每次合法的嵌套都是大的套小的&#xff0c;就相当于找一个最长递增子序列&#xff0c;长度就是能嵌套的最多个数&#xff0c;所以我们可以先对宽度进行升序排序&#xff0c;如果宽度相同就按高度降序排序&…

动态SLAM:如何判断一个特征是动态特征(对极几何)

文章目录 1.什么是极线、极点和极面2.如何判断其为动态点特征3.如何判断其为动态线特征 1.什么是极线、极点和极面 由图可知&#xff0c;C1,C2,X(X1,X2)组成了一个三角平面&#xff0c;这个三角所在的平面就是极面 在这个极平面中&#xff0c;和成像平面相交的线是极线&#xf…

“2024青岛软博会”助力打造“世界工业互联网之都”

在数字经济浪潮的推动下&#xff0c;青岛国际软件融合创新展&#xff08;简称青岛软博会&#xff09;作为年度科技盛宴&#xff0c;不仅全面展示了青岛软件产业发展的辉煌成果&#xff0c;更聚焦于工业软件这一核心领域&#xff0c;为青岛乃至全国的软件产业转型升级注入了强劲…

【gmid】设计一个CS放大器

1.电路原理图 & 电路指标 设计指标&#xff1a; 负载电容CL2 pF增益带宽积GBW100 MHz增益 Av10gm/Id10 2. 根据电路指标进行 手算 2.1 确定 gm 2.2 确定负载电阻 RD 2.3 确定 Id Vov > 150mVgm/id < 10MOS管处于 强反型区Vov < 0gm/id 较大MOS管处于 亚阈值区0…