2025-07-12 15:25:26 +08:00
|
|
|
package middleware
|
|
|
|
|
|
|
|
|
|
import (
|
2025-08-23 16:38:04 +08:00
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
|
|
|
|
"strconv"
|
2025-07-12 15:25:26 +08:00
|
|
|
"time"
|
|
|
|
|
|
2025-08-23 16:38:04 +08:00
|
|
|
"go-admin/app/admin/models"
|
|
|
|
|
"go-admin/common/middleware/handler"
|
|
|
|
|
"go-admin/common/rediskey"
|
|
|
|
|
"go-admin/common/statuscode"
|
|
|
|
|
"go-admin/utils/redishelper"
|
|
|
|
|
|
|
|
|
|
"github.com/bytedance/sonic"
|
|
|
|
|
"github.com/gin-gonic/gin"
|
2025-07-12 15:25:26 +08:00
|
|
|
"github.com/go-admin-team/go-admin-core/sdk/config"
|
2025-08-23 16:38:04 +08:00
|
|
|
"github.com/go-admin-team/go-admin-core/sdk/pkg"
|
2025-07-12 15:25:26 +08:00
|
|
|
jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
|
|
|
|
|
)
|
|
|
|
|
|
2025-08-23 16:38:04 +08:00
|
|
|
var ErrQueryUserId = errors.New("查询用户失败")
|
|
|
|
|
var ErrNoAccount = errors.New("没有API用户")
|
|
|
|
|
var ErrApiUnActived = errors.New("API未激活")
|
|
|
|
|
|
2025-07-12 15:25:26 +08:00
|
|
|
// 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,
|
|
|
|
|
})
|
|
|
|
|
|
2025-08-23 16:38:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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.MemberApiKey, 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 {
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取ApiKey用户id
|
|
|
|
|
func GetUserIdWithApiKey(ctx *gin.Context) (int, error) {
|
|
|
|
|
apikey, ok := ctx.Get("apiKey")
|
|
|
|
|
if !ok {
|
|
|
|
|
return 0, errors.New("apiKey not found")
|
|
|
|
|
}
|
|
|
|
|
return strconv.Atoi(apikey.(string))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取用户id 根据ApiKey
|
|
|
|
|
func GetUserIdByApiKey(c *gin.Context) (int, error) {
|
|
|
|
|
apiKey, ok := c.Get("apiKey")
|
|
|
|
|
if !ok {
|
|
|
|
|
return 0, errors.New("apiKey not found")
|
|
|
|
|
}
|
|
|
|
|
db, err := pkg.GetOrm(c)
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var userId int
|
|
|
|
|
val, err := redishelper.DefaultRedis.GetString(fmt.Sprintf(rediskey.MemberApiKey, apiKey))
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return userId, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if val == "" {
|
|
|
|
|
var user models.MemberApi
|
|
|
|
|
|
|
|
|
|
if dbErr := db.Model(&user).Where("api_key = ?", apiKey).First(&user).Error; dbErr != nil {
|
|
|
|
|
return userId, ErrNoAccount
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if user.Status != 1 {
|
|
|
|
|
return userId, ErrApiUnActived
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
userId = user.UserId
|
|
|
|
|
} else {
|
|
|
|
|
data := models.MemberApi{}
|
|
|
|
|
err = sonic.UnmarshalString(val, &data)
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return userId, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
userId = data.UserId
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return userId, nil
|
|
|
|
|
}
|