You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
OneAuth/auth/middleware.go

85 lines
2.2 KiB
Go

// Copyright (C) 2024 veypi <i@veypi.com>
// 2025-03-04 16:08:06
// Distributed under terms of the MIT license.
1 week ago
package auth
import (
"strings"
1 week ago
"github.com/veypi/vbase/cfg"
"github.com/veypi/vbase/libs/cache"
"github.com/veypi/vbase/libs/jwt"
1 week ago
"github.com/veypi/vbase/models"
"github.com/veypi/vigo"
)
1 week ago
// AuthMiddleware 统一认证中间件
// 1. JWT认证: 解析token验证有效性设置用户信息
// 2. 组织上下文: 如果请求包含org_id验证用户成员身份设置组织信息
func AuthMiddleware() func(*vigo.X) error {
return func(x *vigo.X) error {
1 week ago
// === 1. JWT 认证部分 ===
tokenString := extractToken(x)
if tokenString == "" {
return vigo.ErrNotAuthorized.WithString("missing token")
}
// 解析token
claims, err := jwt.ParseToken(tokenString)
if err != nil {
if err == jwt.ErrExpiredToken {
return vigo.ErrNotAuthorized.WithString("token expired")
}
return vigo.ErrNotAuthorized.WithString("invalid token")
}
// 检查token是否在黑名单中
if cache.IsEnabled() {
blacklisted, _ := cache.IsTokenBlacklisted(claims.ID)
if blacklisted {
return vigo.ErrNotAuthorized.WithString("token has been revoked")
}
}
// 将用户信息存入上下文
x.Set("user_id", claims.UserID)
x.Set("user_name", claims.Username)
x.Set("user_orgs", claims.Orgs)
x.Set("token_claims", claims)
1 week ago
// === 2. 组织上下文部分 ===
orgID := x.Request.Header.Get("X-Org-ID")
if orgID == "" {
orgID = x.Request.URL.Query().Get("org_id")
}
if orgID == "" {
// 没有指定组织,仅完成用户认证
return nil
}
// 验证用户是否为组织成员
var member models.OrgMember
if err := cfg.DB().Where("org_id = ? AND user_id = ? AND status = ?",
orgID, claims.UserID, models.MemberStatusActive).First(&member).Error; err != nil {
return vigo.ErrForbidden.WithString("you are not a member of this organization")
}
x.Set("org_id", orgID)
x.Set("org_roles", member.RoleIDs)
return nil
}
}
func extractToken(x *vigo.X) string {
auth := x.Request.Header.Get("Authorization")
if auth != "" {
if len(auth) > 7 && strings.HasPrefix(auth, "Bearer ") {
return auth[7:]
}
}
return x.Request.URL.Query().Get("access_token")
}