韩国在中国做美食的视频网站有哪些,wordpress 跳转特效,dede cms 网站模板,支付宝网站怎么设计的【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 数据库 【RE…【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简介
JWTJSON Web Token是一种用于身份验证和授权的开放标准RFC 7519它是一种安全的、轻量级的身份验证方式。
JWT由三部分组成头部Header、载荷Payload和签名Signature。
头部HeaderJWT 的头部通常由两部分信息组成令牌的类型即JWT和所使用的签名算法例如
{ alg: HS256, typ: JWT}载荷PayloadJWT的载荷包含了一些声明Claim用于描述用户信息、权限、过期时间等等例如
{ sub: 1234567890, name: John Doe, iat: 1516239022}签名SignatureJWT的签名由头部和载荷组成并使用密钥进行加密生成例如
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 TokenJWT库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-go1.2 创建mytoken项目
全部代码如下
package mainimport (encoding/jsonfmtlognet/httptimejwt github.com/dgrijalva/jwt-go
)// 定义Token的Claims
type CustomClaims struct {Userid string json:useridPasswd string json:passwdjwt.StandardClaims
}// 定义Token相关变量
var (Uid string BLMa //用户名Pwd string 5217 //密码Key string token //密钥Iss string guwuy //签发者
)// 生成新的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)// 签名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, r *http.Request) {//请求参数,实际情况下这里可能从请求参数或身份验证过程中获取query : r.URL.Query()Uid query.Get(userid)Pwd query.Get(passwd)// 这里加uidpwd的数据库校验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() {http.HandleFunc(/generate-token, generateTokenHandler)// Http://localhost:8080/generate-token?usetidblmapasswd5217// curl Http://localhost:8080/generate-token?usetidblma%26passwd5217http.HandleFunc(/validate-token, validateTokenHandler)// curl http://localhost:8080/validate-token -H Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyaWQiOiI5OTk4IiwicGFzc3dkIjoiODk5OSIsImV4cCI6MTcwOTcyMDU0MSwiaXNzIjoiZ3V3dXkifQ.UXiW-cgnDZfGUmLtv_yme6gzFZ9XDiKaNATIdFzJ2fYfmt.Println(Starting server ...)fmt.Println(Http://localhost:8080/generate-token?usetidpasswd)log.Fatal(http.ListenAndServe(:8080, nil))
}
2 实操演练
2.1 启动服务 2.2 获取token
打开浏览器地址栏输入 http://localhost:8080/generate-token?userid9998passwd8999返回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 本文完。