【REST2SQL】11 基于jwt-go生成token与验证

news2025/2/26 4:19:51

【REST2SQL】01RDB关系型数据库REST初设计
【REST2SQL】02 GO连接Oracle数据库
【REST2SQL】03 GO读取JSON文件
【REST2SQL】04 REST2SQL第一版Oracle版实现
【REST2SQL】05 GO 操作 达梦 数据库
【REST2SQL】06 GO 跨包接口重构代码
【REST2SQL】07 GO 操作 Mysql 数据库
【REST2SQL】08 日志重构增加输出到文件log.txt
【REST2SQL】09 给Go的可执行文件exe加图标和版本信息等
【REST2SQL】10 REST2SQL操作指南

0 token 与 jwt 简介

0.1 token简介

Token 本质是字符串,用于请求时附带在请求头中,校验请求是否合法及判断用户身份。
Token 请求时提供,用于校验用户是否具备访问接口的权限。
Token 的用途主要有三点:

  • 拦截无效请求,降低服务器处理压力;
  • 实现第三方 API授权,无需每次都输入用户名密码鉴权;
  • 身份校验,防止 CSRF 攻击。

0.2 jwt简介

JWT(JSON Web Token)是一种用于身份验证和授权的开放标准(RFC 7519),它是一种安全的、轻量级的身份验证方式。

JWT由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。

头部(Header):JWT 的头部通常由两部分信息组成:令牌的类型(即JWT)和所使用的签名算法,例如:

{  "alg": "HS256",  "typ": "JWT"}

载荷(Payload):JWT的载荷包含了一些声明(Claim),用于描述用户信息、权限、过期时间等等,例如:

{  "sub": "1234567890",  "name": "John Doe",  "iat": 1516239022}

签名(Signature):JWT的签名由头部和载荷组成,并使用密钥进行加密生成,例如:

HMACSHA256(  base64UrlEncode(header) + "." +  base64UrlEncode(payload),  secret)

0.2.1 JWT 的使用流程如下:

用户使用用户名和密码进行登录,服务器验证用户信息是否正确。
服务器生成一个JWT,将用户信息、权限等信息写入载荷中,并使用密钥对头部和载荷进行签名。
服务器将生成的JWT返回给客户端,客户端将其存储在本地,通常是在浏览器的cookie或本地存储中。
客户端在后续的请求中,将JWT作为请求头部或请求参数传递给服务器。
服务器收到请求后,验证JWT的签名是否正确,如果正确则解析出用户信息、权限等信息,进行后续操作。

0.2.2 JWT 的优点:

无状态:JWT是无状态的,服务器不需要保存任何会话信息,可以轻松扩展和分布式环境下使用。
安全:JWT通过密钥对头部和载荷进行签名,保证了数据的完整性和安全性。
跨域支持:JWT可以跨域使用,可以在不同的域名和服务器之间使用。
简单易用:JWT使用简单,易于实现和维护。

0.2.3 JWT 的缺点:

载荷信息不能太多:JWT的载荷信息不能太多,否则会导致JWT的长度过长,增加网络传输的负担。
安全性依赖于密钥:JWT的安全性依赖于密钥的保护,如果密钥泄露,则JWT的安全性将受到威胁。
无法撤销:一旦JWT生成后,无法撤销,除非修改密钥或者设置短期的过期时间

1 基于jwt-go实现token服务端

JWT-Go是一个使用Go语言实现的JSON Web Token(JWT)库1。

JWT是一种跨域认证解决方案,属于一个开放的标准,它规定了一种Token实现方式,目前多用于前后端分离项目和OAuth2.0业务场景下。JWT-Go库提供了创建和验证JWT的方法,包括使用默认Claims和自定义Claims来创建Token对象,以及解析和验证Token的有效性等。JWT-Go库在Go语言社区中广泛使用,并且有许多配置选项可供选择,可以满足不同的业务需求。

1.1 安装jwt-go库

go get github.com/dgrijalva/jwt-go

1.2 创建mytoken项目

全部代码如下:

package main

import (
	"crypto/rand"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"time"

	jwt "github.com/dgrijalva/jwt-go"
)

// 定义Token的Claims
type CustomClaims struct {
	Userid string `json:"userid"`
	Passwd string `json:"passwd"`
	jwt.StandardClaims
}

// 定义Token相关变量
var (
	Uid         string = "BLMa"            //用户名
	Pwd         string = "5217"            //密码
	Key         string = "token"           //密钥
	Iss         string = "guwuy"           //签发者
	timeStamp   int64  = time.Now().Unix() // 时间戳,用于定期更新密钥key
	timeSecond  int64  = 60 * 60 * 24 * 7  //一周时间的秒数,用于7天修改一次Key
	timeExpires int64  = 60 * 60 * 8       // Token 过期时间 秒数,8小时
)

// GenerateRandomString 生成一个指定长度的随机字符串
func GenerateRandomString(length int) (string, error) {
	const letters = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	bytes := make([]byte, length)
	if _, err := rand.Read(bytes); err != nil {
		return "", err
	}
	for i, b := range bytes {
		bytes[i] = letters[b%byte(len(letters))]
	}
	return string(bytes), nil
}

// 定期生成随机Key
func GenerateRandomKey() {
	//当前时间戳
	timestamp := time.Now().Unix()
	if (timestamp-timeStamp > timeSecond) || len(Key) < 10 {
		// 修改Key
		Key, err := GenerateRandomString(16)
		if err != nil {
			log.Fatal(err)
		}
		timeStamp = timestamp // 更新Key修改的时间戳

		// 打印时间戳
		fmt.Println("timeStamp :", timeStamp, time.Unix(timeStamp, 0))
		fmt.Println("Random String:", Key)
	}
}

// 生成新的Token
func generateToken(userid string) (string, error) {
	// 设置Claims
	claims := CustomClaims{
		Userid: userid,
		Passwd: Pwd,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: time.Now().Add(time.Second * 5217).Unix(), // 设置过期时间
			Issuer:    Iss,                                       // 设置签发者
		},
	}

	// 创建Token
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

	// 定期生成随机Key
	GenerateRandomKey()
	// 签名Token,这里使用硬编码的密钥,实际生产环境中应使用更安全的密钥管理方式
	signedToken, err := token.SignedString([]byte(Key))
	if err != nil {
		return "", err
	}

	return signedToken, nil
}

// 验证Token
func validateToken(tokenString string) (*CustomClaims, error) {
	// 解析Token
	token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
		// 验证Token的签名,这里使用硬编码的密钥
		return []byte(Key), nil
	})

	if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
		return claims, nil
	}

	return nil, err
}

// HTTP处理函数:生成Token
func generateTokenHandler(w http.ResponseWriter, r *http.Request) {
	//请求参数,实际情况下,这里可能从请求参数或身份验证过程中获取
	query := r.URL.Query()
	Uid = query.Get("userid")
	Pwd = query.Get("passwd")
	// 这里加uid,pwd的数据库校验

	token, err := generateToken(Uid)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(map[string]string{
		"token": token,
	})
}

// HTTP处理函数:验证Token
func validateTokenHandler(w http.ResponseWriter, r *http.Request) {
	tokenString := r.Header.Get("Authorization") // 假设Token在Authorization头中

	claims, err := validateToken(tokenString)
	if err != nil {
		http.Error(w, err.Error(), http.StatusUnauthorized)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(map[string]interface{}{
		"userid":  claims.Userid,
		"expires": claims.ExpiresAt,
	})
}

// main入口
func main() {
	// 检查并生成Key
	GenerateRandomKey()

	// Token 路由
	http.HandleFunc("/generate-token", generateTokenHandler)
	// Http://localhost:8080/generate-token?userid=blma&passwd=5217
	// curl Http://localhost:8080/generate-token?userid=blma%26passwd=5217
	http.HandleFunc("/validate-token", validateTokenHandler)
	//curl http://localhost:8080/validate-token -H "Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyaWQiOiI5OTk4IiwicGFzc3dkIjoiODk5OSIsImV4cCI6MTcwOTcyMDU0MSwiaXNzIjoiZ3V3dXkifQ.UXiW-cgnDZfGUmLtv_yme6gzFZ9XDiKaNATIdFzJ2fY"

	fmt.Println("Starting server ...")
	fmt.Println("Http://localhost:8080/generate-token?userid=&passwd=")
	log.Fatal(http.ListenAndServe(":8080", nil))
}


2 实操演练

2.1 启动服务

在这里插入图片描述

2.2 获取token

打开浏览器地址栏输入:

 http://localhost:8080/generate-token?userid=9998&passwd=8999

在这里插入图片描述

返回token

{
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyaWQiOiI5OTk4IiwicGFzc3dkIjoiODk5OSIsImV4cCI6MTcwOTcyMDU0MSwiaXNzIjoiZ3V3dXkifQ.UXiW-cgnDZfGUmLtv_yme6gzFZ9XDiKaNATIdFzJ2fY"
}

2.3 验证token

cmd窗口输入curl如下命令:

curl http://localhost:8080/validate-token -H "Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyaWQiOiI5OTk4IiwicGFzc3dkIjoiODk5OSIsImV4cCI6MTcwOTcyMDU0MSwiaXNzIjoiZ3V3dXkifQ.UXiW-cgnDZfGUmLtv_yme6gzFZ9XDiKaNATIdFzJ2fY"

在这里插入图片描述

返回token的失效时间和用户id:

{"expires":1709720541,"userid":"9998"}

其中时间戳 1709720541 对应的时间为:2024-03-06 18:22:21


本文完。

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

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

相关文章

设计模式学习系列 -- 随记

文章目录 前言 一、设计模式是什么&#xff1f; 二、设计模式的历史 三、为什么以及如何学习设计模式&#xff1f; 四、关于模式的争议 一种针对不完善编程语言的蹩脚解决方案 低效的解决方案 不当使用 五、设计模式分类 总结 前言 最近可能工作生活上的稳定慢慢感觉自己丢失…

掌握 Vue3、Vite 和 SCSS 实现一键换肤的魔法步骤

前言 一个网站的换肤效果算是一个比较常见的功能&#xff0c;尤其是在后台管理系统中&#xff0c;我们几乎都能看到他的身影&#xff0c;这里给大家提供一个实现思路。 搭建项目 vitevue3搭建项目这里就不演示了&#xff0c;vite官网里面讲得很清楚。 注&#xff1a;这里使…

浅析开源内存数据库Fastdb

介绍&#xff1a; Fastdb是免费开源内存数据库&#xff0c;其优秀的性能&#xff0c;和简洁的C代码&#xff0c;让我学习使用过程中收益颇多&#xff0c;但是国内中文相关研究的文章相当稀少&#xff0c;外文我查询相当不便。有兴趣的朋友可以通过以下网站访问&#xff1a;Mai…

java-ssm-jsp基于ssm的冰淇淋在线购买网站

java-ssm-jsp基于ssm的冰淇淋在线购买网站 获取源码——》公主号&#xff1a;计算机专业毕设大全

【STM32】HAL库 CubeMX 教程 --- 通用定时器 TIM2 定时

实验目标&#xff1a; 通过CUbeMXHAL&#xff0c;配置TIM2&#xff0c;1s中断一次&#xff0c;闪烁LED。 一、常用型号的TIM时钟频率 1. STM32F103系列&#xff1a; 所有 TIM 的时钟频率都是72MHz&#xff1b;F103C8不带基本定时器&#xff0c;F103RC及以上才带基本定时器。…

react实战——react旅游网

慕课网react实战 搭建项目问题1.按照官网在index.tsx中引入antd出错&#xff1f;2.typescript中如何使用react-router3.react-router3.1 V63.2 V53.3V6实现私有路由 4.函数式组件接收props参数时定义数据接口&#xff1f;5.使用TypeScript开发react项目&#xff1a;6.要使一个组…

探索stable diffusion的奇妙世界--01

目录 1. 理解prompt提示词&#xff1a; 2. Prompt中的技术参数&#xff1a; 3. Prompt中的Negative提示词&#xff1a; 4. Prompt中的特殊元素&#xff1a; 5. Prompt在stable diffusion中的应用&#xff1a; 6. 作品展示&#xff1a; 在AI艺术领域&#xff0c;stable di…

数据结构——线性表顺序表示详解

目录 1.线性表的类型定义 2.基本操作 3.线性表的存储结构 4.补充 1.元素类型说明 2.数组定义​编辑 3.c语言的内存动态分配 4.c的动态存储分配 5.c中的参数传递 引用类型作参数 6.顺序表基本操作的实现 1.线性表的初始化 代码示例&#xff1a; 2.销毁线性表&…

远程连接Linux系统

图形化、命令行 对于操作系统的使用&#xff0c;有2种使用形式&#xff1a; 图形化页面使用操作系统 图形化&#xff1a;使用操作系统提供的图形化页面&#xff0c;以获得图形化反馈的形式去使用操作系统。 以命令的形式使用操作系统 命令行&#xff1a;使用操作系统提供的各…

腾讯云轻量服务器Windows系统使用IIS实现公网直链访问文件

windows方便所以服务器装的windows系统&#xff0c;windows默认不能分享文件直链&#xff0c;只要用IIS建个站点就行了 先弄一台有公网ip的windows系统服务器打开服务器管理器&#xff0c;添加这个 打开IIS右键添加网站 程序池默认&#xff0c;路径选个文件夹作为网站根目录 …

tomcat通过service.bat install方式安装,内存不够了怎么办?

1.通过service.bat安装 安装命令再tomcat的bin目录下&#xff0c;执行命令 .\service.bat install Apache Tomcat 8.5 Tomcat8之后就会在服务里面有个tomcat服务 2. 如何增加tomcat内存呢&#xff1f; 通过service.bat安装肯定再service.bat中配置啊。 再service.bat文件中…

RHCE——一、OpenEuler22.03安装部署及例行性任务

RHCE 一、OpenEuler22.03安装部署及例行性任务 一、网络服务1.准备工作2、RHEL9操作系统的安装部署3、配置并优化OpenEuler22.034、网络配置实验&#xff1a;修改网络配置 二、例行性工作1、 单一执行的例行性任务&#xff1a;at&#xff08;一次性&#xff09;at命令详解 2、循…

MQTT连接阿里云物联网上报物模型数据

目录 1. 创建产品&#xff08;物联网平台 -> 产品 -> 创建产品&#xff09; 2. 为产品添加设备 3. 添加物模型 4. mqtt.fx连接测试 5. 调试物模型 6. 使用mqtt.fx上报温度数据 1. 创建产品&#xff08;物联网平台 -> 产品 -> 创建产品&#xff09; 我这里再新…

企业内部培训考试系统首页自定义版块说明

企业内部培训考试系统首页自定义版块说明&#xff0c;企业内部培训考试系统手机端首页设计太灵活。 1、整站主题色自定义&#xff0c;更换主题色后&#xff0c;重要的文字和按钮颜色都自动使用主题色渲染&#xff0c;相当于一键换皮肤。 2、首页背景图自定义&#xff0c;想换…

【蓝牙协议栈】【经典蓝牙】【BLE蓝牙】蓝牙技术特点

目录 1. 蓝牙技术特点 2. 经典蓝牙与BLE蓝牙对比 2.1 BT/BLE技术区分 2.2 支持的profile不同 2.3 核心架构&#xff0c;不同的controler 3. Bluetooth的系统构成 4. 蓝牙协议规范 4.1 传输协议 4.2 中介协议 4.3 应用协议 5. 蓝牙硬件接口 1. 蓝牙技术特点 简单地说…

论文笔记:Compact Multi-Party Confidential Transactions

https://link.springer.com/chapter/10.1007/978-3-030-65411-5_21 A compact, private, Multi-Party Confidential Transactions (MCT) 紧凑型多方机密交易&#xff08;Compact MCT&#xff09;&#xff1a;MCT的长度与常规的单一所有者交易一样短&#xff1b;换句话说&…

【STM32+HAL】GY25倾斜度角度模块

一、前言 有关MPU6050模块读取六轴传感器数值的详细内容&#xff0c;详见【STM32HAL】姿态传感器陀螺仪MPU6050模块 二、所用工具 1、芯片&#xff1a;STM32F103C8T6 2、配置软件&#xff1a;CUBEMX 3、编译器&#xff1a;KEIL5 4、产品型号&#xff1a;GY-25 5、使用芯片…

【SpringMVC】RESTFul风格设计和实战 第三期

文章目录 概述一、 RESTFul风格简介二、 RESTFul风格特点三、 RESTFul风格设计规范3.1 HTTP协议请求方式要求3.2 URL路径风格要求 实战一、需求分析二、RESTFul风格接口设计三、后台接口实现总结模糊查询 有范围 返回多数据用户 添加 与 更新 请求参数接收数据显示用户详情/删除…

配电网数字化转型全面推进:《关于新形势下配电网高质量发展的指导意见》

近日&#xff0c;国家发展改革委、国家能源局印发了《关于新形势下配电网高质量发展的指导意见》&#xff08;以下简称《意见》&#xff09;&#xff0c;到2030年&#xff0c;基本完成配电网柔性化、智能化、数字化转型&#xff0c;实现主配微网多级协同、海量资源聚合互动、多…

Unity3d C#实现文件(json、txt、xml等)加密、解密和加载(信息脱敏)功能实现(含源码工程)

前言 在Unity3d工程中经常有需要将一些文件放到本地项目中&#xff0c;诸如json、txt、csv和xml等文件需要放到StreamingAssets和Resources文件夹目录下&#xff0c;在程序发布后这些文件基本是对用户可见的状态&#xff0c;造成信息泄露&#xff0c;甚至有不法分子会利用这些…