【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"
)// 定义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 = 60 * 60 * 24 * 7  //一周时间的秒数,用于7天修改一次KeytimeExpires 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 {// 修改KeyKey, 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) {// 设置Claimsclaims := customClaims{userid: userid,passwd: pwd,StandardClaims: jwt.StandardClaims{ExpiresAt: time.Now().Add(time.Second * 5217).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的数据库校验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 服务日志

在这里插入图片描述


本文完。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python实现霍德里克-普雷斯科特(Hodrick-Prescott,HP)过滤器模型和UC-ARIMA模型(hpfilter算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 霍德里克-普雷斯科特&#xff08;Hodrick-Prescott, HP&#xff09;过滤器模型&#xff1a; HP滤波器是…

防御保护----IPSEC VPPN实验

实验拓扑&#xff1a; 实验背景&#xff1a;FW1和FW2是双机热备的状态。 实验要求&#xff1a;在FW和FW3之间建立一条IPSEC通道&#xff0c;保证10.0.2.0/24网段可以正常访问到192.168.1.0/24 IPSEC VPPN实验配置&#xff08;由于是双机热备状态&#xff0c;所以FW1和FW2只需要…

【Linux】第一个小程序--进度条

这篇博客要综合利用以前的知识&#xff0c;来实现一个进度条程序~ 目录 换行&回车 缓冲区 实现简单的倒计时 实现进度条 version1 version2 在开始写这个小程序之前&#xff0c;我们先学习一些预备知识&#xff1a; 换行&回车 缓冲区 在我们运行这个程序时&…

AWTK-MVVM 文件模型

AWTK-MVVM 文件模型 名称&#xff1a;file 功能&#xff1a;用于读写文件内容&#xff0c;浏览&#xff08;打开/保存&#xff09;文件。 内置属性 属性类型说明filenamestring文件名contentstring文件内容sizenumber文件大小auto_loadboolean是否自动加载文件内容is_dirtyb…

开关电源安规测试标准与测试要求

安规测试是对开关电源进行电气性能、安全性能等检测&#xff0c;确保开关电源符合规定并且安全可靠&#xff0c;为开关电源的质量把关。那么开关电源安规测试有哪些测试要求和标准呢&#xff1f; 开关电源安规测试要求 一、测试前 1. 首先&#xff0c;要检查测试环境&#xff0…

关于esp8266的一些经验汇总,新手必看

说实话&#xff0c;esp8266的nodemcu 已经使用了2年多了&#xff0c;各种问题遇到过&#xff0c;就尝试各种解决&#xff0c;而现在回头来看真的是稀里糊涂的在用&#xff0c;当然这个问题也同样涉及到esp32. 因为最近打算自己打一块esp8266的板&#xff0c;之前打的比较多的是…

基于Vue的兴趣活动推荐APP的设计与实现

目 录 摘 要 I Abstract II 引 言 1 1 相关技术简介 3 1.1 框架 3 1.1.1 Spring MVC 3 1.1.2 Spring框架 3 1.1.3 MyBatis框架 3 1.1.4 VUE框架 3 1.2 开发语言 3 1.2.1 JAVA 3 1.2.2 JavaScript 4 1.3 设计模式 4 1.4 数据库 4 2 可行性分析 5 2.1 社会可行性 5 2.2 经济可行…

2024年泰迪智能科技合作伙伴战略大会暨产教融合实训基地落成仪式圆满结束

2024年泰迪智能科技合作伙伴战略大会 暨产教融合实训基地落成仪式 3月6日&#xff0c;2024年泰迪智能科技合作伙伴战略大会暨产教融合实训基地落成仪式在泰迪智能科技产教融合实训基地举行&#xff0c;本次合作伙伴战略大会围绕“龙腾山海&#xff0c;共赴新程 ”主题开展&…

Python自动化测试:API接口自动化——requests、webSocket

接口自动化测试1 一、requests二、简单示例1.导入/引入库2.请求与响应示例1>简单访问百度主页-GET请求2>简单的登录请求-POST请求3>保存cookies至头信息headers4>其他接口请求时携带headers 三、webSocketwebSocket连接与数据收发示例 本文介绍了借助Python的reque…

全志D1s裸机开发之体验第一个程序

体验第一个程序 2.1 编译烧录运行 2.1.1 编译 先进入源码目录&#xff0c;打开 Git Bash&#xff0c;如下图操作&#xff1a; 然后在 Git Bash 中执行 make 命令&#xff0c;可以生成 benos_payload.bin 文件&#xff0c;如下图所示&#xff1a; 2.1.2 烧录运行 使用 2 条 …

Windows上基于名称快速定位文件和文件夹的免费工具Everything

在Windows上搜索文件时&#xff0c;使用windows上内置搜索会很慢&#xff0c;这里推荐使用Everything工具进行搜索。 "Everything"是Windows上一款搜索引擎&#xff0c;它能够基于文件名快速定位文件和文件夹位置。不像Windows内置搜索&#xff0c;"Everything&…

微软Win32K权限提升漏洞修复处理

一、漏洞描述 近日安全扫描发现&#xff0c;本地windows主机涉及【Microsoft Win32K权限提升漏洞】&#xff1b;其中&#xff0c;Microsoft Win32k是微软&#xff08;Microsoft&#xff09;公司的一个用于Windows多用户管理的系统文件。Microsoft Win32K存在权限提升漏洞&…