package utils import ( "github.com/gin-gonic/gin" "net" "sundynix-go/global" "sundynix-go/model/system" systemReq "sundynix-go/model/system/request" "time" ) // GetLoginToken 获取登录token func GetLoginToken(user system.Login) (token string, claims systemReq.CustomClaims, err error) { j := NewJWT() claims = j.CreateClaims(systemReq.BaseClaims{ Account: user.GetAccount(), ID: user.GetUserId(), }) token, err = j.CreateToken(claims) return } // SetToken 设置一个名为 "x-token" 的 Cookie,并根据请求的主机名和 IP 地址来设置 Cookie 的域。 // // 参数: // - c: *gin.Context, Gin 框架的上下文对象,用于处理 HTTP 请求和响应。 // - token: string, 要设置的 token 值。 // - maxAge: int, Cookie 的最大生存时间(以秒为单位)。 // // 该函数首先从请求的主机名中提取出主机部分(去除端口号),然后判断该主机名是否为 IP 地址。 // 如果是 IP 地址,则设置 Cookie 的域为空;否则,将 Cookie 的域设置为提取出的主机名。 func SetToken(c *gin.Context, token string, maxAge int) { // 从请求的主机名中提取主机部分,忽略端口号 host, _, err := net.SplitHostPort(c.Request.Host) if err != nil { host = c.Request.Host } // 判断主机名是否为 IP 地址,并根据结果设置 Cookie 的域 if net.ParseIP(host) != nil { c.SetCookie("x-token", token, maxAge, "/", "", false, false) } else { c.SetCookie("x-token", token, maxAge, "/", host, false, false) } } // GetToken 从请求头或Cookie中获取JWT token,并确保其有效性。 // 如果请求头中没有Authorization字段,则尝试从Cookie中获取token,并解析验证其有效性。 // 如果token有效,则将其重新写入Cookie,并设置过期时间。 // // 参数: // - c: *gin.Context, Gin框架的上下文对象,用于获取请求信息和设置响应。 // // 返回值: // - string: 获取到的JWT token,如果获取失败则返回空字符串。 func GetToken(c *gin.Context) string { // 从请求头中获取Authorization字段的值 token := c.Request.Header.Get("Authorization") // 如果请求头中没有Authorization字段,则尝试从Cookie中获取token if token == "" { j := NewJWT() token, _ = c.Cookie("x-token") // 解析并验证token的有效性 claims, err := j.ParseToken(token) if err != nil { // 如果解析失败,记录错误日志并返回当前token global.Logger.Error("重新写入cookie token失败,未能成功解析token,请检查请求头是否存在x-token且claims是否为规定结构") return token } // 如果token有效,则将其重新写入Cookie,并设置过期时间 SetToken(c, token, int((claims.ExpiresAt.Unix()-time.Now().Unix())/60)) } // 返回获取到的token return token } // GetUserInfo 从 gin.Context 中获取用户信息,并返回 CustomClaims 类型的指针。 // 该函数首先尝试从上下文中获取已存在的 claims,如果不存在,则调用 GetClaims 函数获取 claims。 // 如果获取 claims 失败,则返回 nil。 // // 参数: // - c: *gin.Context, gin 框架的上下文对象,用于获取请求相关的信息。 // // 返回值: // - *systemReq.CustomClaims: 返回用户的自定义 claims 信息,如果获取失败则返回 nil。 func GetUserInfo(c *gin.Context) *systemReq.CustomClaims { // 尝试从上下文中获取已存在的 claims if claims, exists := c.Get("claims"); !exists { // 如果 claims 不存在,则调用 GetClaims 函数获取 claims if cl, err := GetClaims(c); err != nil { // 如果获取 claims 失败,返回 nil return nil } else { // 成功获取 claims,返回 claims return cl } } else { // 如果 claims 存在,将其转换为 CustomClaims 类型并返回 waitUse := claims.(*systemReq.CustomClaims) return waitUse } } // GetUserId 从 gin.Context 中获取用户 ID,并返回 uint 类型的 ID。 // 该函数首先尝试从上下文中获取已存在的 claims,如果不存在,则调用 GetClaims 函数获取 claims。 // 如果获取 claims 失败,则返回 0。 // // 参数: // - c: *gin.Context, gin 框架的上下文对象,用于获取请求相关的信息。 // // 返回值: // - uint: 返回用户的 ID,如果获取失败则返回 0。 func GetUserId(c *gin.Context) uint { if claims, exists := c.Get("claims"); !exists { if cl, err := GetClaims(c); err != nil { return 0 } else { return cl.BaseClaims.ID } } else { waitUse := claims.(*systemReq.CustomClaims) return waitUse.BaseClaims.ID } } // GetClaims 从 Gin 上下文中提取并解析 JWT 令牌,返回自定义的 claims 信息。 // 该函数首先从请求头中获取 JWT 令牌,然后使用 JWT 解析器解析令牌并返回 claims。 // 如果解析过程中发生错误,函数会记录错误日志并返回错误信息。 // // 参数: // - c: *gin.Context, Gin 上下文对象,用于获取请求头中的 JWT 令牌。 // // 返回值: // - *systemReq.CustomClaims: 解析后的自定义 claims 信息。 // - error: 解析过程中发生的错误,如果解析成功则为 nil。 func GetClaims(c *gin.Context) (*systemReq.CustomClaims, error) { // 从 Gin 上下文中获取 JWT 令牌 token := GetToken(c) // 创建新的 JWT 解析器 j := NewJWT() // 解析 JWT 令牌并获取 claims 信息 claims, err := j.ParseToken(token) if err != nil { // 如果解析失败,记录错误日志 global.Logger.Error("获取用户信息失败,请检查请求头是否存在x-token且claims是否为规定结构") } // 返回解析后的 claims 信息和可能的错误 return claims, err }