Some checks failed
Build / build (push) Has been cancelled
CodeQL / Analyze (go) (push) Has been cancelled
build / Build (push) Has been cancelled
GitHub Actions Mirror / mirror_to_gitee (push) Has been cancelled
GitHub Actions Mirror / mirror_to_gitlab (push) Has been cancelled
Issue Close Require / issue-close-require (push) Has been cancelled
Issue Check Inactive / issue-check-inactive (push) Has been cancelled
179 lines
5.4 KiB
Go
179 lines
5.4 KiB
Go
package middleware
|
||
|
||
import (
|
||
"fmt"
|
||
"time"
|
||
|
||
"go-admin/common/middleware/handler"
|
||
rediskey "go-admin/common/redis_key"
|
||
"go-admin/common/statuscode"
|
||
"go-admin/utils/redishelper"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
"github.com/go-admin-team/go-admin-core/sdk/config"
|
||
jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
|
||
)
|
||
|
||
// AuthInit jwt验证new
|
||
func AuthInit() (*jwt.GinJWTMiddleware, error) {
|
||
timeout := time.Hour
|
||
if config.ApplicationConfig.Mode == "dev" {
|
||
timeout = time.Duration(876010) * time.Hour
|
||
} else {
|
||
if config.JwtConfig.Timeout != 0 {
|
||
timeout = time.Duration(config.JwtConfig.Timeout) * time.Second
|
||
}
|
||
}
|
||
return jwt.New(&jwt.GinJWTMiddleware{
|
||
Realm: "test zone",
|
||
Key: []byte(config.JwtConfig.Secret),
|
||
Timeout: timeout,
|
||
MaxRefresh: time.Hour,
|
||
PayloadFunc: handler.PayloadFunc,
|
||
IdentityHandler: handler.IdentityHandler,
|
||
Authenticator: handler.Authenticator,
|
||
Authorizator: handler.Authorizator,
|
||
Unauthorized: handler.Unauthorized,
|
||
TokenLookup: "header: Authorization, query: token, cookie: jwt",
|
||
TokenHeadName: "Bearer",
|
||
TimeFunc: time.Now,
|
||
})
|
||
|
||
}
|
||
|
||
// apikey授权认证
|
||
func FrontedAuth(c *gin.Context) {
|
||
// 从请求头中获取 token 和 os
|
||
apikey := c.GetHeader("x-api-key")
|
||
// 如果 token 不存在,返回未登录的状态
|
||
if len(apikey) == 0 {
|
||
err := ResponseWithStatus(c, statuscode.Unauthorized)
|
||
if err != nil {
|
||
return
|
||
}
|
||
c.Abort() // 停止后续中间件的执行
|
||
return
|
||
}
|
||
// 验证 token 并获取结果
|
||
key := fmt.Sprintf(rediskey.TM_MEMBER_BY_KEY, apikey)
|
||
val, err := redishelper.DefaultRedis.GetString(key)
|
||
|
||
if err != nil || val == "" {
|
||
ResponseWithStatus(c, statuscode.Unauthorized)
|
||
c.Abort() // 停止后续中间件的执行
|
||
}
|
||
|
||
// 将解析后的 token 设置到请求头中
|
||
c.Set("apiKey", apikey)
|
||
// 继续处理请求
|
||
c.Next()
|
||
}
|
||
|
||
// ResponseWithStatus 带状态的响应
|
||
func ResponseWithStatus(ctx *gin.Context, code int, data ...interface{}) error {
|
||
// 获取语言对应的 msg
|
||
// msg := statuscode.GetStatusCodeDescription(ctx, code)
|
||
// if msg == `` {
|
||
// msg = strconv.Itoa(code)
|
||
// } else {
|
||
// // 配置了语言包参数
|
||
// if strings.Contains(msg, "%") && len(data) > 1 {
|
||
// msg = fmt.Sprintf(msg, data[1:]...)
|
||
// }
|
||
// }
|
||
|
||
resp := statuscode.Response{
|
||
Code: code,
|
||
Msg: "un authorized",
|
||
}
|
||
|
||
// resp.RequestID = pkg.GenerateMsgIDFromContext(ctx)
|
||
if len(data) > 0 {
|
||
resp.Data = data[0]
|
||
}
|
||
|
||
switch code {
|
||
case 401, 500, 405, 404:
|
||
ctx.JSON(code, resp)
|
||
default:
|
||
ctx.JSON(200, resp)
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// func AuthApiInit() (*jwt.GinJWTMiddleware, error) gin.HandlerFunc {
|
||
// return func(c *gin.Context) {
|
||
// // 1. 从请求头或查询参数中获取 API Key
|
||
// // 优先从 Header "X-API-Key" 获取,其次从查询参数 "api_key" 获取
|
||
// apiKey := c.GetHeader("X-API-Key")
|
||
// if apiKey == "" {
|
||
// apiKey = c.Query("api_key")
|
||
// }
|
||
|
||
// // 2. 检查 API Key 是否存在
|
||
// if apiKey == "" {
|
||
// logger.Debug("API Key not provided in header or query parameter.")
|
||
// response.Unauthorized(c, "API Key is required.")
|
||
// c.Abort() // 终止请求处理链
|
||
// return
|
||
// }
|
||
|
||
// // 3. 验证 API Key 的有效性
|
||
// // 实际项目中,这里需要查询数据库或缓存来验证 API Key,并获取其关联的用户ID或权限
|
||
// // 伪代码示例:
|
||
// // user, isValid := service.AuthService.ValidateApiKey(apiKey)
|
||
// // if !isValid {
|
||
// // response.Unauthorized(c, "Invalid API Key.")
|
||
// // c.Abort()
|
||
// // return
|
||
// // }
|
||
// // c.Set("user_id", user.ID) // 将关联的用户ID设置到 Gin Context 中
|
||
|
||
// // 简化示例:从配置中获取一个硬编码的有效 API Key
|
||
// // **警告:生产环境中,绝不能硬编码 API Key!这只是一个演示。**
|
||
// // 假设 config.APIKeyConfig.ValidKeys 是一个 map[string]string,存储 apiKey -> userID 的映射
|
||
// // 或者 config.APIKeyConfig.MasterKey 是一个单一的预设主密钥
|
||
|
||
// isValid := false
|
||
// associatedUserID := "" // 存储与 API Key 关联的用户ID
|
||
|
||
// // 假设 API Key 存储在 config.APIKeyConfig 中,例如:
|
||
// // type APIKeyConfig struct {
|
||
// // MasterKey string `mapstructure:"master_key"`
|
||
// // ValidKeys map[string]string `mapstructure:"valid_keys"` // key: API Key, value: UserID
|
||
// // }
|
||
// // 你可能需要根据你的 config.go 中 API Key 配置的实际结构来调整
|
||
|
||
// // 示例:检查是否是 MasterKey
|
||
// if apiKey == config.APIKeyConfig.MasterKey { // 假设你有一个MasterKey
|
||
// isValid = true
|
||
// associatedUserID = "platform_admin" // 或者一个特殊的管理员ID
|
||
// } else {
|
||
// // 示例:检查是否在有效键列表中
|
||
// for key, uid := range config.APIKeyConfig.ValidKeys { // 假设 ValidKeys 是一个 map
|
||
// if apiKey == key {
|
||
// isValid = true
|
||
// associatedUserID = uid
|
||
// break
|
||
// }
|
||
// }
|
||
// }
|
||
|
||
// if !isValid {
|
||
// logger.Warnf("Attempted to use invalid API Key: %s", apiKey)
|
||
// response.Unauthorized(c, "Invalid API Key.")
|
||
// c.Abort()
|
||
// return
|
||
// }
|
||
|
||
// // 4. API Key 验证成功,将关联的用户ID或信息设置到 Gin Context
|
||
// // 这样后续的业务逻辑(如翻译服务中的扣费)就可以通过 c.GetString("user_id") 获取到用户身份
|
||
// c.Set("user_id", associatedUserID)
|
||
// logger.Debugf("API Key authenticated successfully for user: %s", associatedUserID)
|
||
|
||
// // 5. 继续处理请求
|
||
// c.Next()
|
||
// }
|
||
// }
|