fix
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
|||||||
"tydata-server/app/main/api/internal/config"
|
"tydata-server/app/main/api/internal/config"
|
||||||
"tydata-server/app/main/model"
|
"tydata-server/app/main/model"
|
||||||
jwtx "tydata-server/common/jwt"
|
jwtx "tydata-server/common/jwt"
|
||||||
|
"tydata-server/common/result"
|
||||||
"tydata-server/common/xerr"
|
"tydata-server/common/xerr"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@@ -50,19 +51,21 @@ func (m *AdminAuthInterceptorMiddleware) Handle(next http.HandlerFunc) http.Hand
|
|||||||
// 1. JWT 校验
|
// 1. JWT 校验
|
||||||
claims, err := m.validateJWT(r)
|
claims, err := m.validateJWT(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
httpx.Error(w, err)
|
m.writeUnauthorizedResponse(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 检查用户类型是否为管理员
|
// 2. 检查用户类型是否为管理员
|
||||||
if claims.UserType != model.UserTypeAdmin {
|
if claims.UserType != model.UserTypeAdmin {
|
||||||
httpx.Error(w, errors.Wrapf(xerr.NewErrCode(xerr.TOKEN_EXPIRE_ERROR), "用户类型错误,需要管理员权限"))
|
authErr := errors.Wrapf(xerr.NewErrCode(xerr.TOKEN_EXPIRE_ERROR), "用户类型错误,需要管理员权限")
|
||||||
|
m.writeUnauthorizedResponse(w, authErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 检查平台标识
|
// 3. 检查平台标识
|
||||||
if claims.Platform != model.PlatformAdmin {
|
if claims.Platform != model.PlatformAdmin {
|
||||||
httpx.Error(w, errors.Wrapf(xerr.NewErrCode(xerr.TOKEN_EXPIRE_ERROR), "平台标识错误,需要管理员平台"))
|
authErr := errors.Wrapf(xerr.NewErrCode(xerr.TOKEN_EXPIRE_ERROR), "平台标识错误,需要管理员平台")
|
||||||
|
m.writeUnauthorizedResponse(w, authErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +75,7 @@ func (m *AdminAuthInterceptorMiddleware) Handle(next http.HandlerFunc) http.Hand
|
|||||||
|
|
||||||
// 5. API 权限校验
|
// 5. API 权限校验
|
||||||
if err := m.validateApiPermission(r.Context(), claims.UserId, r.Method, r.URL.Path); err != nil {
|
if err := m.validateApiPermission(r.Context(), claims.UserId, r.Method, r.URL.Path); err != nil {
|
||||||
httpx.Error(w, err)
|
m.writeUnauthorizedResponse(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,23 +84,45 @@ func (m *AdminAuthInterceptorMiddleware) Handle(next http.HandlerFunc) http.Hand
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// writeUnauthorizedResponse 写入401未授权响应
|
||||||
|
func (m *AdminAuthInterceptorMiddleware) writeUnauthorizedResponse(w http.ResponseWriter, err error) {
|
||||||
|
errcode := xerr.TOKEN_EXPIRE_ERROR
|
||||||
|
errmsg := xerr.MapErrMsg(errcode)
|
||||||
|
|
||||||
|
// 从错误中提取错误码和错误消息
|
||||||
|
causeErr := errors.Cause(err)
|
||||||
|
if e, ok := causeErr.(*xerr.CodeError); ok {
|
||||||
|
errcode = e.GetErrCode()
|
||||||
|
errmsg = e.GetErrMsg()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回401 HTTP状态码
|
||||||
|
httpx.WriteJson(w, http.StatusUnauthorized, result.Error(errcode, errmsg))
|
||||||
|
}
|
||||||
|
|
||||||
// validateJWT 验证JWT token
|
// validateJWT 验证JWT token
|
||||||
func (m *AdminAuthInterceptorMiddleware) validateJWT(r *http.Request) (*jwtx.JwtClaims, error) {
|
func (m *AdminAuthInterceptorMiddleware) validateJWT(r *http.Request) (*jwtx.JwtClaims, error) {
|
||||||
// 从请求头中获取Authorization字段
|
// 从请求头中获取Authorization字段
|
||||||
authHeader := r.Header.Get("Authorization")
|
authHeader := r.Header.Get("Authorization")
|
||||||
if authHeader == "" {
|
if authHeader == "" {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(AdminErrCodeUnauthorized), "缺少Authorization头")
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.TOKEN_EXPIRE_ERROR), "缺少Authorization头")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 去掉Bearer前缀
|
// 去掉Bearer前缀
|
||||||
token := strings.TrimPrefix(authHeader, "Bearer ")
|
token := strings.TrimPrefix(authHeader, "Bearer ")
|
||||||
if token == authHeader {
|
if token == authHeader {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(AdminErrCodeUnauthorized), "Authorization头格式错误,缺少Bearer前缀")
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.TOKEN_EXPIRE_ERROR), "Authorization头格式错误,缺少Bearer前缀")
|
||||||
}
|
}
|
||||||
|
|
||||||
claims, err := jwtx.ParseJwtToken(token, m.Config.AdminConfig.AccessSecret)
|
claims, err := jwtx.ParseJwtToken(token, m.Config.AdminConfig.AccessSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(AdminErrCodeUnauthorized), "token解析失败: %v", err)
|
// 根据错误类型返回不同的错误码
|
||||||
|
errMsg := err.Error()
|
||||||
|
if strings.Contains(errMsg, "token已过期") || strings.Contains(errMsg, "expired") {
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.TOKEN_EXPIRE_ERROR), "token解析失败: %v", err)
|
||||||
|
}
|
||||||
|
// 其他JWT解析错误使用统一的token过期错误码(更符合用户理解)
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.TOKEN_EXPIRE_ERROR), "token解析失败: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return claims, nil
|
return claims, nil
|
||||||
|
|||||||
@@ -66,12 +66,29 @@ func ParseJwtToken(tokenStr string, secret string) (*JwtClaims, error) {
|
|||||||
return []byte(secret), nil
|
return []byte(secret), nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil || !token.Valid {
|
if err != nil {
|
||||||
|
// 检查是否是JWT验证错误
|
||||||
|
if validationErr, ok := err.(*jwt.ValidationError); ok {
|
||||||
|
// 如果是过期错误,返回更明确的错误信息
|
||||||
|
if validationErr.Errors&jwt.ValidationErrorExpired != 0 {
|
||||||
|
return nil, errors.New("token已过期")
|
||||||
|
}
|
||||||
|
// 如果是签名错误,返回签名错误信息
|
||||||
|
if validationErr.Errors&jwt.ValidationErrorSignatureInvalid != 0 {
|
||||||
|
return nil, errors.New("token签名无效")
|
||||||
|
}
|
||||||
|
// 其他验证错误
|
||||||
|
return nil, errors.New("token验证失败")
|
||||||
|
}
|
||||||
return nil, errors.New("invalid JWT")
|
return nil, errors.New("invalid JWT")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !token.Valid {
|
||||||
|
return nil, errors.New("token无效")
|
||||||
|
}
|
||||||
|
|
||||||
claims, ok := token.Claims.(jwt.MapClaims)
|
claims, ok := token.Claims.(jwt.MapClaims)
|
||||||
if !ok || !token.Valid {
|
if !ok {
|
||||||
return nil, errors.New("invalid JWT claims")
|
return nil, errors.New("invalid JWT claims")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user