go jwt 用户登录和返回用户信息 token ----important!!!
1.每一行代码都有详细注释,解释了其功能和作用。这些注释可以帮助你理解代码如何工作,特别是在处理用户登录、生成 JWT、验证 JWT 和返回用户信息的过程中。
package main // 指定这个文件是一个可执行程序import ("fmt" // 标准库包,用于格式化字符串和输出到控制台"github.com/dgrijalva/jwt-go" // 第三方库,用于处理 JWT"github.com/gin-gonic/gin" // 第三方库,用于构建 Web API"net/http" // 标准库包,提供 HTTP 客户端和服务器实现"time" // 标准库包,提供时间的基本操作
)var jwtKey = []byte("your_secret_key") // 用于签名 JWT 的密钥// Claims 定义了包含用户信息的自定义 JWT 结构
type Claims struct {Identity int `json:"identity"` // 用户 IDjwt.StandardClaims // 域包含 JWT 标准的声明,如过期时间、发布者等
}func main() {r := gin.Default() // 创建一个默认的 Gin 路由器实例r.POST("/login", login) // 定义 POST 方法的 /login 路由,处理用户登录请求r.GET("/user", authenticate, getUserId) // 定义 GET 方法的 /user 路由,先进行用户验证再获取用户 ID// 生成一个有效的 JWT token 并打印出来generateAndPrintToken()r.Run(":8080") // 启动服务器,监听端口 8080
}// login 处理用户登录请求,生成 JWT token 并返回给客户端
func login(c *gin.Context) {identity := 135 // 模拟用户的 ID// 创建包含用户 ID 和过期时间的 JWT claimsexpirationTime := time.Now().Add(5 * time.Minute) // 设置 token 的过期时间为当前时间的 5 分钟后claims := &Claims{Identity: identity, // 设置用户的 IDStandardClaims: jwt.StandardClaims{ExpiresAt: expirationTime.Unix(), // 设置 JWT 的过期时间},}// 创建 JWT tokentoken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) // 使用 HS256 签名方法创建 JWTtokenString, err := token.SignedString(jwtKey) // 使用密钥签名生成 JWTif err != nil {c.JSON(http.StatusInternalServerError, gin.H{"error": "无法创建token"}) // 如果签名失败,返回 500 错误return}// 返回 token 给客户端c.JSON(http.StatusOK, gin.H{"token": tokenString})
}// authenticate 中间件,验证请求是否携带有效的 JWT token
func authenticate(c *gin.Context) {tokenString := c.GetHeader("Authorization") // 从请求头中获取 Authorization 字段的值// 解析 tokenclaims := &Claims{}token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {return jwtKey, nil // 返回用于签名的密钥})if err != nil || !token.Valid { // 如果解析或验证失败c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "无效的token"}) // 中止请求并返回 401 错误return}// 将 claims 保存到上下文中,以便后续处理使用c.Set("claims", claims)c.Next() // 继续处理下一个处理函数
}// getUserId 从上下文中提取用户 ID 并返回给客户端
func getUserId(c *gin.Context) {data := ExtractClaims(c) // 从上下文中提取 claimsif data == nil {fmt.Println(fmt.Sprintf("%s [WARNING] %s %s GetUserId 缺少 identity", time.Now().Format(time.RFC3339), c.Request.Method, c.Request.URL.Path))c.JSON(http.StatusUnauthorized, gin.H{"error": "无法获取用户ID"}) // 如果没有提取到 claims,返回 401 错误return}//identity := data.Identity // 获取用户 ID//c.JSON(http.StatusOK, gin.H{"userId": identity}) // 返回用户 ID 给客户端c.JSON(http.StatusOK, gin.H{"data": data}) // 返回用户 ID 给客户端
}// ExtractClaims 从上下文中提取 JWT claims
func ExtractClaims(c *gin.Context) *Claims {claims, exists := c.Get("claims") // 从上下文中获取 claimsif !exists {return nil // 如果 claims 不存在,返回 nil}return claims.(*Claims) // 返回 claims
}// generateAndPrintToken 生成一个新的 JWT token 并打印到控制台
func generateAndPrintToken() {identity := 135 // 模拟用户的 ID// 创建包含用户 ID 和过期时间的 JWT claimsexpirationTime := time.Now().Add(5 * time.Minute) // 设置 token 的过期时间为当前时间的 5 分钟后claims := &Claims{Identity: identity, // 设置用户的 IDStandardClaims: jwt.StandardClaims{ExpiresAt: expirationTime.Unix(), // 设置 JWT 的过期时间},}// 创建 JWT tokentoken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) // 使用 HS256 签名方法创建 JWTtokenString, err := token.SignedString(jwtKey) // 使用密钥签名生成 JWTif err != nil {fmt.Println("无法创建token:", err) // 如果签名失败,打印错误return}fmt.Println("生成的token:", tokenString) // 打印生成的 token
}
2.好的,我们可以将代码分为两个部分:一个处理用户登录,并生成 JWT token;另一个验证 JWT token 并返回用户信息。以下是详细分类和注释:
(1)用户登录部分
package main // 指定这个文件是一个可执行程序import ("fmt" // 标准库包,用于格式化字符串和输出到控制台"net/http" // 标准库包,提供 HTTP 客户端和服务器实现"time" // 标准库包,提供时间的基本操作"github.com/dgrijalva/jwt-go" // 第三方库,用于处理 JWT"github.com/gin-gonic/gin" // 第三方库,用于构建 Web API
)var jwtKey = []byte("your_secret_key") // 用于签名 JWT 的密钥// Claims 定义了包含用户信息的自定义 JWT 结构
type Claims struct {Identity int `json:"identity"` // 用户 IDjwt.StandardClaims // 域包含 JWT 标准的声明,如过期时间、发布者等
}func main() {r := gin.Default() // 创建一个默认的 Gin 路由器实例r.POST("/login", login) // 定义 POST 方法的 /login 路由,处理用户登录请求r.GET("/user", authenticate, getUserId) // 定义 GET 方法的 /user 路由,先进行用户验证再获取用户 ID// 生成一个有效的 JWT token 并打印出来generateAndPrintToken()r.Run(":8080") // 启动服务器,监听端口 8080
}// 用户登录部分:处理用户登录请求,生成 JWT token 并返回给客户端
func login(c *gin.Context) {identity := 135 // 模拟用户的 ID// 创建包含用户 ID 和过期时间的 JWT claimsexpirationTime := time.Now().Add(5 * time.Minute) // 设置 token 的过期时间为当前时间的 5 分钟后claims := &Claims{Identity: identity, // 设置用户的 IDStandardClaims: jwt.StandardClaims{ExpiresAt: expirationTime.Unix(), // 设置 JWT 的过期时间},}// 创建 JWT tokentoken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) // 使用 HS256 签名方法创建 JWTtokenString, err := token.SignedString(jwtKey) // 使用密钥签名生成 JWTif err != nil {c.JSON(http.StatusInternalServerError, gin.H{"error": "无法创建token"}) // 如果签名失败,返回 500 错误return}// 返回 token 给客户端c.JSON(http.StatusOK, gin.H{"token": tokenString})
}// generateAndPrintToken 生成一个新的 JWT token 并打印到控制台
// 仅用于辅助测试,在实际应用中可能不会使用
func generateAndPrintToken() {identity := 135 // 模拟用户的 ID// 创建包含用户 ID 和过期时间的 JWT claimsexpirationTime := time.Now().Add(5 * time.Minute) // 设置 token 的过期时间为当前时间的 5 分钟后claims := &Claims{Identity: identity, // 设置用户的 IDStandardClaims: jwt.StandardClaims{ExpiresAt: expirationTime.Unix(), // 设置 JWT 的过期时间},}// 创建 JWT tokentoken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) // 使用 HS256 签名方法创建 JWTtokenString, err := token.SignedString(jwtKey) // 使用密钥签名生成 JWTif err != nil {fmt.Println("无法创建token:", err) // 如果签名失败,打印错误return}fmt.Println("生成的token:", tokenString) // 打印生成的 token
}
(2)返回用户信息部分
// authenticate 中间件,验证请求是否携带有效的 JWT token
// 适用于返回用户信息的部分
func authenticate(c *gin.Context) {tokenString := c.GetHeader("Authorization") // 从请求头中获取 Authorization 字段的值// 解析 tokenclaims := &Claims{}token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {return jwtKey, nil // 返回用于签名的密钥})if err != nil || !token.Valid { // 如果解析或验证失败c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "无效的token"}) // 中止请求并返回 401 错误return}// 将 claims 保存到上下文中,以便后续处理使用c.Set("claims", claims)c.Next() // 继续处理下一个处理函数
}// getUserId 从上下文中提取用户 ID 并返回给客户端
// 适用于返回用户信息的部分
func getUserId(c *gin.Context) {data := ExtractClaims(c) // 从上下文中提取 claimsif data == nil {fmt.Println(fmt.Sprintf("%s [WARNING] %s %s GetUserId 缺少 identity", time.Now().Format(time.RFC3339), c.Request.Method, c.Request.URL.Path))c.JSON(http.StatusUnauthorized, gin.H{"error": "无法获取用户ID"}) // 如果没有提取到 claims,返回 401 错误return}identity := data.Identity // 获取用户 IDc.JSON(http.StatusOK, gin.H{"userId": identity}) // 返回用户 ID 给客户端
}// ExtractClaims 从上下文中提取 JWT claims
// 适用于返回用户信息的部分
func ExtractClaims(c *gin.Context) *Claims {claims, exists := c.Get("claims") // 从上下文中获取 claimsif !exists {return nil // 如果 claims 不存在,返回 nil}return claims.(*Claims) // 返回 claims
}
3.测试:
获取token:

使用生成的 JWT token 测试
在 Postman 中,按照以下步骤:
- 创建一个新的
GET请求。 - 设置 URL 为
http://localhost:8080/user。 - 在请求头中添加一个新的头字段
Authorization,值为你在上面生成的 JWT token。 - 点击 "Send" 按钮。
你将会收到包含用户 ID 的 JSON 响应。

相关文章:
go jwt 用户登录和返回用户信息 token ----important!!!
1.每一行代码都有详细注释,解释了其功能和作用。这些注释可以帮助你理解代码如何工作,特别是在处理用户登录、生成 JWT、验证 JWT 和返回用户信息的过程中。 package main // 指定这个文件是一个可执行程序import ("fmt" …...
OpenCV高级图形用户界面(12)用于更改指定窗口的大小函数resizeWindow()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 cv::resizeWindow() 函数用于更改指定窗口的大小。这使得你可以根据需要调整窗口的宽度和高度。 注释 指定的窗口大小是指图像区域的大小。工具栏…...
babylonjs shader学习之copy shadertoy案例
shadertoy案例: 准备 const onSceneReady (scene: Scene) > {const light new HemisphericLight(light, new Vector3(0, 1, 0), scene);light.intensity 0.7;Effect.ShadersStore[planeMatVertexShader] precision highp float;attribute vec3 position;attr…...
Leetcode 1137. 第 N 个泰波那契数
原题链接:Leetcode 1137. 第 N 个泰波那契数 代码1: class Solution { public:int a[40];int tribonacci(int n) {a[0]0;a[1]1;a[2]1;if(n<1) return n;if(a[n]) return a[n];a[n]tribonacci(n-1)tribonacci(n-2)tribonacci(n-3);return a[n];} };代…...
Rust 语言持续崛起,即将冲击 TIOBE 指数前十,能否成为编程语言新王者?
Rust 语言持续崛起,即将冲击 TIOBE 指数前十,能否成为编程语言新王者? 2024 年 10 月,全球编程语言 TIOBE 排行榜再次更新,各大编程语言在各自领域中继续发挥着独特的优势。官方的标题是: Rust排名稳步攀升…...
Linux 手撕线程池
前言 线程池 是 池化技术 中很典型的一个,它旨在高效的管理和复用线程资源!在现在的计算机体系中,线程是执行任务(调度)的基本单位。然而,频繁的创建和销毁线程也会带来较大的开销,包括系统资源…...
[Unity Demo]从零开始制作空洞骑士Hollow Knight第十五集:制作更多地图,更多敌人,更多可交互对象
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、第一个代表性场景 1.制作更多敌人2.制作更多可交互对象二、第二个代表性场景 1.制作更多敌人2.制作更多可交互对象三、第三个代表性场景 1.制作更多敌人2.制…...
在Openshift上安装MetalLB
1.部署MetalLB Operator 2.部署AddressPool addresses 必须和ocp节点在同一网段 apiVersion: metallb.io/v1beta1 kind: AddressPool metadata:name: metallb-ipaddressnamespace: metallb-system spec:addresses:- 192.168.1.51-192.168.1.60- 192.168.1.61-192.168.1.70aut…...
mysql其他对象
一、存储引擎 mysql的存储引擎包括: InnoDB,MyISAM,Memory(Heap),Archive,CSV,NDB Cluster 常用的只有前两个。 InnoDB与MyISAM的区别: InnoDB 简介:Inn…...
英语单词之社会生活之聚会
一些关于聚会的单词和短语 句子 English中文What’s the plan?计划是什么?I’m going out with some friends.我要跟几个朋友一起出去。I don’t really feel like going out.我不是很想出去。What time suits you ?你什么时间合适?Where shall we m…...
Qt - 地图相关 —— 1、加载百度在线地图(附源码)
效果图 开始加载地图 1、百度地图开发者网站中注册,获取密钥 2、进入开发文档中 将下图内容保存到本地文件中,文件名为"index.html"文件即可。接着将内容中的“您的密钥”改为刚刚创建应用出来的AK密钥即可。 然后双击打开若在浏览器中正常看到下图右侧地图则说明没…...
Elasticsearch 简单使用
Elasticsearch 安装和基本操作 一、引言 Elasticsearch 是一个基于 Lucene 构建的开源分布式搜索引擎,提供了实时的搜索和数据分析能力。它广泛应用于日志分析、全文搜索、数据可视化等场景。本文将详细介绍 Elasticsearch 的安装步骤及基本操作,包括索…...
基于SpringBoot+Vue+uniapp微信小程序的垃圾分类系统的详细设计和实现(源码+lw+部署文档+讲解等)
项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念,提供了一套默认的配置,让开发者可以更专注于业务逻辑而不是配置文件。Spring Boot 通过自动化配置和约…...
基于深度学习的车辆车型检测识别系统(YOLOV5)
界面图: 项目简介: 网络:深度学习网络 yoloV5 软件:PycharmAnaconda 环境:python3.8 opencv PyQt5 torch1.9 文件:训练集8000张图片 测试集1000张图片 系统包含所有文件夹 环境文件 UI文件 功能&a…...
Java开发中知识点整理
正则表达式 测试网址 Git 分支和主分支有冲突 先checkout origin/分支把origin/master pull进本地分支 修改冲突MergeCommit and Push...
【css-在一个元素中设置font-size和实际渲染字体大小不一致】
首先,这个不是bug,是Chromium内核提高移动端文本可读性的一个特性,叫做这个特性被称做「Text Autosizer」,又称「Font Boosting」、「Font Inflation」 解决方案: 使用-webkit-text-size-adjust 给元素设置 -webkit-te…...
LabVIEW提高开发效率技巧----用户权限控制
在LabVIEW开发中,用户权限控制是一个重要的设计模块,尤其在多用户系统中,它可以确保数据安全并控制不同用户的操作权限。为了实现用户权限控制,可以通过角色与权限管理模块来进行设计和实施。以下将从多个角度详细说明如何在LabVI…...
如何快速学会盲打
今天就来给大家分享一下如何快速学会盲打 盲打的基本方法和步骤 手指放置:将双手放在键盘上,左手食指放在F键上,右手食指放在J键上,其他手指分别放在相邻的键位上。熟悉键盘布局:学习26个字母的位置,以及…...
如何通过外链组合套餐提升外贸网站的整体表现?
在SEO优化中,单一的外链形式很难覆盖所有需求,特别是对于那些竞争激烈的行业。通过高低搭配的外链组合套餐成为越来越多企业的选择 简单来说,外链组合套餐是将不同质量、不同类型的外链进行合理搭配,从而最大化地提升网站的多维度…...
MySQL—事务
目录 1.事务的简介: 2.使用事务 2.1 开启事务 2.2 自动提交 2.3 使用范围 2.4 事务的属性 1.事务的简介: 介绍事务之前,我们先来看一个经典的场景:银行转账。 假如a想要把自己的账户上的10万块钱转到b账户上,这…...
Rustup终极指南:轻松管理你的Rust开发环境
Rustup终极指南:轻松管理你的Rust开发环境 【免费下载链接】rustup The Rust toolchain installer 项目地址: https://gitcode.com/gh_mirrors/ru/rustup 你是否曾经为管理多个Rust版本而烦恼?或者在不同项目间切换工具链时感到困惑?R…...
C++技术岗面试经验总结
🎬 胖咕噜的稞达鸭:个人主页🔥 个人专栏: 《数据结构》《C初阶高阶》 《Linux系统学习》 《算法日记》⛺️技术的杠杆,撬动整个世界! 1. 右值引用和左值引用的区别 左值是我们平常使用的函数对象,表达式结束后依旧存在…...
零基础入门:REX-UniNLU中文NLP系统保姆级安装与使用指南
零基础入门:REX-UniNLU中文NLP系统保姆级安装与使用指南 1. 为什么选择REX-UniNLU系统 如果你正在寻找一个简单易用但功能强大的中文自然语言处理工具,REX-UniNLU可能是你的理想选择。这个系统最大的特点就是"开箱即用"——不需要复杂的配置…...
PyTorch Playground量化评估报告:不同bit宽度的精度损失分析
PyTorch Playground量化评估报告:不同bit宽度的精度损失分析 【免费下载链接】pytorch-playground Base pretrained models and datasets in pytorch (MNIST, SVHN, CIFAR10, CIFAR100, STL10, AlexNet, VGG16, VGG19, ResNet, Inception, SqueezeNet) 项目地址: …...
CefFlashBrowser:让Flash内容在现代系统中延续生命的技术方案
CefFlashBrowser:让Flash内容在现代系统中延续生命的技术方案 【免费下载链接】CefFlashBrowser Flash浏览器 / Flash Browser 项目地址: https://gitcode.com/gh_mirrors/ce/CefFlashBrowser 问题引入:Flash技术的现代困境与解决方案 随着主流浏…...
3分钟上手的跨平台模组管理神器:Lumafly核心优势解析
3分钟上手的跨平台模组管理神器:Lumafly核心优势解析 【免费下载链接】Lumafly A cross platform mod manager for Hollow Knight written in Avalonia. 项目地址: https://gitcode.com/gh_mirrors/lu/Lumafly 还在为空洞骑士模组安装时的依赖缺失而头疼&am…...
手把手教你用NVIDIA TX2串口控制大疆C620电机(USB转CAN模块保姆级教程)
从零实现NVIDIA TX2通过USB-CAN模块精准控制大疆C620电机 硬件连接与基础原理 当我们需要在机器人项目中实现高精度电机控制时,CAN总线通信往往是首选方案。但对于使用NVIDIA Jetson TX2这类开发板的新手来说,可能会遇到两个现实问题:TX2原生…...
新手必看!UI-TARS-desktop快速上手:一句话让电脑自动干活
新手必看!UI-TARS-desktop快速上手:一句话让电脑自动干活 你是否想过,只需要对电脑说一句话,它就能自动完成各种任务?UI-TARS-desktop正是这样一个神奇的AI助手,它能听懂你的自然语言指令,并自…...
用Logisim从零搭建一个数字秒表:手把手教你理解计数器、比较器和数码管驱动
用Logisim从零搭建数字秒表:模块化设计与实战解析 数字逻辑设计是计算机科学和电子工程的基础课程,但很多初学者在学习过程中常常陷入"知道原理却不会动手"的困境。Logisim作为一款开源的数字电路仿真工具,为我们提供了将抽象理论转…...
深入剖析mini-swe-agent:100行核心代码如何实现高效编程助手
1. 初识mini-swe-agent:极简主义的力量 第一次看到mini-swe-agent的GitHub仓库时,我完全被它的极简设计震撼了。作为一个常年与复杂代码库打交道的开发者,很难想象一个能解决真实编程问题的AI助手,核心逻辑竟然只有100行Python代码…...
