【REST2SQL】12 REST2SQL增加Token生成和验证

2024-03-09 20:36

本文主要是介绍【REST2SQL】12 REST2SQL增加Token生成和验证,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【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操作指南
【REST2SQL】11 基于jwt-go生成token与验证


【REST2SQL】11 基于jwt-go生成token与验证的Token生成和验证合并到【REST2SQL】

1 Rest2sql目录下新建token子目录

  • Rest2sql目录下新建token子目录
  • 拷贝 【REST2SQL】11 基于jwt-go生成token与验证 的mytoken.go
  • mytoken.go改名为 token.go
    在这里插入图片描述

2 token.go的代码重构

  • 包名改为token
  • 屏蔽或删除 main()入口函数
  • 重构全局变量,都改为外部不可见,即变量名改为首字母改为小写即可
  • 只暴露生成token函数GenerateTokenHandler()和验证token函数ValidateTokenHandler()
  • 暴露函数第二个参数重构

重构完成的代码如下:

package tokenimport ("crypto/rand""encoding/json""fmt""log""net/http""time"jwt "github.com/dgrijalva/jwt-go"
)// 初始化函数
func init() {// 实例化计数计时器counter = NewCounter()// 初始化随机 Keykey, err := generateRandomString(16)if err != nil {log.Fatal(err)}// 打印时间戳fmt.Println("Start At timeStamp :", timeStamp, time.Unix(timeStamp, 0), key)
}// Counter 定义一个简单的计数器
type Counter struct {value      inttimeStampc int64 // 时间戳,用于定期更新密钥key
}// 计时器变量实例
var counter *Counter// NewCounter 创建一个新的计数器
func NewCounter() *Counter {return &Counter{value: 0, timeStampc: time.Now().Unix()}
}// Increment 增加计数器的值
func (c *Counter) Increment() {c.value++c.timeStampc = time.Now().Unix()
}// // Decrement 减少计数器的值
// func (c *Counter) Decrement() {
// 	c.value--
// }// // Reset 重置计数器的值为0
// func (c *Counter) Reset() {
// 	c.value = 0
// }// GetValue 返回计数器的当前值
func (c *Counter) GetCounter() *Counter {return c
}// 
// 定义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() // 时间戳,用于定期更新密钥keytimeSecond  int64         = 20                //60 * 60 * 24 * 7  //一周时间的秒数,用于7天修改一次KeytimeExpires time.Duration = 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 := counter.GetCounter().timeStampc//fmt.Println("Now timeStamp,timestamp:", timeStamp, timestamp)if timestamp-timeStamp > timeSecond {counter.Increment()// 修改Keykey, err := generateRandomString(16)if err != nil {log.Fatal(err)}timeStamp = timestamp // 更新Key修改的时间戳// 打印时间戳fmt.Println("Now timeStamp :", timeStamp, time.Unix(timeStamp, 0), key)}
}// 生成新的Token
func generateToken(userId string) (string, error) {// 计数器,计时器counter.Increment()// 设置Claimsclaims := customClaims{Userid: userId,Passwd: pwd,StandardClaims: jwt.StandardClaims{ExpiresAt: time.Now().Add(time.Second * timeExpires).Unix(), // 设置过期时间Issuer:    iss,                                              // 设置签发者},}// 创建Tokentoken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)// 定期生成随机KeygenerateRandomKey()// 签名Token,这里使用硬编码的密钥,实际生产环境中应使用更安全的密钥管理方式signedToken, err := token.SignedString([]byte(key))if err != nil {return "", err}return signedToken, nil
}// 验证Token
func validateToken(tokenString string) (*customClaims, error) {// 解析Tokentoken, 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, uid_pwd map[string]string) {//请求参数,实际情况下,这里可能从请求参数或身份验证过程中获取uid = uid_pwd["Userid"]pwd = uid_pwd["Passwd"]// 这里加uid,pwd的数据库校验//fmt.Println(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, tokenString string) {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 Token server ...")
// 	fmt.Println("Http://localhost:8080/generate-token?userid=&passwd=")
// 	fmt.Println("curl http://localhost:8080/validate-token -H \"Authorization:token\"")
// 	log.Fatal(http.ListenAndServe(":8080", nil))
// }

3 rest2sql.go的 handler() 增加token访问路由

重构的核心代码如下:

  • 请求路径错误提示代码:
// 2请求路径Pathreq["Path"] = r.URL.Pathpath := strings.Split(r.URL.Path, "/")if len(path) < 3 {w.Write([]byte("400 Bad Request错误请求。请尝试/rest/xxx or /sql/xxx or /TOKEN/xxx"))return}
  • 允许的请求路径代码:
// 3 请求类型REST or SQL or Tokenrors := strings.ToUpper(fmt.Sprint(path[1]))// 支持的请求类型if !(rors == "REST" || rors == "SQL" || rors == "TOKEN") {w.Write([]byte("400 Bad Request错误请求。请尝试/REST/xxx or /SQL/xxx or /TOKEN/xxx"))return}
  • 请求头token结构代码:
// 8 请求头 Authorizationreq["Authorization"] = r.Header.Get("Authorization") // 假设Token在Authorization头中
  • 请求参数增加userid和passw代码:
// 9 请求参数query := r.URL.Query()req["Userid"] = query.Get("userid") // 登录用户req["Passwd"] = query.Get("passwd") // 登录密码

3 dothing.go代码重构

分支代码:
case "TOKEN":// Token 生成与校验doTOKEN(w, req)
  • doTiken函数代码:
// 根据请求参数执行不同的TOKEN操作 ///
func doTOKEN(w http.ResponseWriter, req map[string]interface{}) {// token操作, generate or validateresToken := strings.ToLower(req["ResName"].(string))switch resToken {case "generate-token":// w.Write([]byte("generate-token"))var uid_pwd map[string]string = make(map[string]string)uid_pwd["Userid"] = req["Userid"].(string)uid_pwd["Passwd"] = req["Passwd"].(string)token.GenerateTokenHandler(w, uid_pwd)// http://127.0.0.1:5217/TOKEN/generate-token?userid=9998&passwd=8999case "validate-token"://w.Write([]byte("validate-token"))var tokenString string = req["Authorization"].(string)token.ValidateTokenHandler(w, tokenString)// curl http://localhost:5217/token/validate-token -H "Authorization:token"}
}

4 实操演练

Setp 1 启动服务

在这里插入图片描述

Step 2 生成Token

http://127.0.0.1:5217/TOKEN/generate-token?userid=9998&passwd=8999

在这里插入图片描述

Step 3 验证Token

curl http://localhost:5217/token/validate-token -H "Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MDk4Njk0OTEsImlzcyI6Imd1d3V5In0.7CLaQKNXZOhnirLfOb_1meYYnc6KVDkXUhrxbfvYgKw"

在这里插入图片描述

Step 4 服务日志

在这里插入图片描述


本文完。

这篇关于【REST2SQL】12 REST2SQL增加Token生成和验证的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/791880

相关文章

Python实现自动化Word文档样式复制与内容生成

《Python实现自动化Word文档样式复制与内容生成》在办公自动化领域,高效处理Word文档的样式和内容复制是一个常见需求,本文将展示如何利用Python的python-docx库实现... 目录一、为什么需要自动化 Word 文档处理二、核心功能实现:样式与表格的深度复制1. 表格复制(含样式与内容)2

python如何生成指定文件大小

《python如何生成指定文件大小》:本文主要介绍python如何生成指定文件大小的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录python生成指定文件大小方法一(速度最快)方法二(中等速度)方法三(生成可读文本文件–较慢)方法四(使用内存映射高效生成

Maven项目中集成数据库文档生成工具的操作步骤

《Maven项目中集成数据库文档生成工具的操作步骤》在Maven项目中,可以通过集成数据库文档生成工具来自动生成数据库文档,本文为大家整理了使用screw-maven-plugin(推荐)的完... 目录1. 添加插件配置到 pom.XML2. 配置数据库信息3. 执行生成命令4. 高级配置选项5. 注意事

SpringBoot整合Sa-Token实现RBAC权限模型的过程解析

《SpringBoot整合Sa-Token实现RBAC权限模型的过程解析》:本文主要介绍SpringBoot整合Sa-Token实现RBAC权限模型的过程解析,本文给大家介绍的非常详细,对大家的学... 目录前言一、基础概念1.1 RBAC模型核心概念1.2 Sa-Token核心功能1.3 环境准备二、表结

MybatisX快速生成增删改查的方法示例

《MybatisX快速生成增删改查的方法示例》MybatisX是基于IDEA的MyBatis/MyBatis-Plus开发插件,本文主要介绍了MybatisX快速生成增删改查的方法示例,文中通过示例代... 目录1 安装2 基本功能2.1 XML跳转2.2 代码生成2.2.1 生成.xml中的sql语句头2

CentOS7增加Swap空间的两种方法

《CentOS7增加Swap空间的两种方法》当服务器物理内存不足时,增加Swap空间可以作为虚拟内存使用,帮助系统处理内存压力,本文给大家介绍了CentOS7增加Swap空间的两种方法:创建新的Swa... 目录在Centos 7上增加Swap空间的方法方法一:创建新的Swap文件(推荐)方法二:调整Sww

使用Python自动化生成PPT并结合LLM生成内容的代码解析

《使用Python自动化生成PPT并结合LLM生成内容的代码解析》PowerPoint是常用的文档工具,但手动设计和排版耗时耗力,本文将展示如何通过Python自动化提取PPT样式并生成新PPT,同时... 目录核心代码解析1. 提取 PPT 样式到 jsON关键步骤:代码片段:2. 应用 JSON 样式到

SpringBoot实现二维码生成的详细步骤与完整代码

《SpringBoot实现二维码生成的详细步骤与完整代码》如今,二维码的应用场景非常广泛,从支付到信息分享,二维码都扮演着重要角色,SpringBoot是一个非常流行的Java基于Spring框架的微... 目录一、环境搭建二、创建 Spring Boot 项目三、引入二维码生成依赖四、编写二维码生成代码五

Android与iOS设备MAC地址生成原理及Java实现详解

《Android与iOS设备MAC地址生成原理及Java实现详解》在无线网络通信中,MAC(MediaAccessControl)地址是设备的唯一网络标识符,本文主要介绍了Android与iOS设备M... 目录引言1. MAC地址基础1.1 MAC地址的组成1.2 MAC地址的分类2. android与I

PyQt5+Python-docx实现一键生成测试报告

《PyQt5+Python-docx实现一键生成测试报告》作为一名测试工程师,你是否经历过手动填写测试报告的痛苦,本文将用Python的PyQt5和python-docx库,打造一款测试报告一键生成工... 目录引言工具功能亮点工具设计思路1. 界面设计:PyQt5实现数据输入2. 文档生成:python-