diff --git a/backend/internal/logic/auth/loginlogic.go b/backend/internal/logic/auth/loginlogic.go index d529956..1d86b87 100644 --- a/backend/internal/logic/auth/loginlogic.go +++ b/backend/internal/logic/auth/loginlogic.go @@ -66,7 +66,7 @@ func (l *LoginLogic) Login(req *types.LoginRequest) (resp *types.LoginResponse, }, nil } - token, err := jwt.GenerateToken(user.Id, user.Username, user.Role) + token, err := jwt.GenerateToken(user.Id, user.Username, user.Role, user.CurrentOrgId) if err != nil { return nil, fmt.Errorf("生成Token失败: %v", err) } diff --git a/backend/internal/logic/auth/refreshtokenlogic.go b/backend/internal/logic/auth/refreshtokenlogic.go index 1c0ad92..88e9ef3 100644 --- a/backend/internal/logic/auth/refreshtokenlogic.go +++ b/backend/internal/logic/auth/refreshtokenlogic.go @@ -52,7 +52,7 @@ func (l *RefreshTokenLogic) RefreshToken(req *types.RefreshTokenRequest) (resp * } // 生成新 Token - newToken, err := jwt.GenerateToken(user.Id, user.Username, user.Role) + newToken, err := jwt.GenerateToken(user.Id, user.Username, user.Role, user.CurrentOrgId) if err != nil { return nil, fmt.Errorf("生成Token失败: %v", err) } diff --git a/backend/internal/logic/auth/ssologic.go b/backend/internal/logic/auth/ssologic.go index a5a96a9..1ddfc74 100644 --- a/backend/internal/logic/auth/ssologic.go +++ b/backend/internal/logic/auth/ssologic.go @@ -176,7 +176,7 @@ func (l *SSOLogic) HandleCallback(code, state string) (string, error) { } // 4. 生成本地 JWT Token - token, err := jwt.GenerateToken(localUser.Id, localUser.Username, localUser.Role) + token, err := jwt.GenerateToken(localUser.Id, localUser.Username, localUser.Role, localUser.CurrentOrgId) if err != nil { return "", fmt.Errorf("生成 Token 失败: %v", err) } diff --git a/backend/internal/middleware/authmiddleware.go b/backend/internal/middleware/authmiddleware.go index 56a6a47..2e8d4ce 100644 --- a/backend/internal/middleware/authmiddleware.go +++ b/backend/internal/middleware/authmiddleware.go @@ -18,15 +18,19 @@ func (m *AuthMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // 从 Header 中获取 Token authHeader := r.Header.Get("Authorization") - if authHeader == "" { - http.Error(w, "Unauthorized", http.StatusUnauthorized) - return + var tokenString string + if authHeader != "" { + // Token 格式: "Bearer " + tokenString = strings.TrimPrefix(authHeader, "Bearer ") + } + + // 回退: 从 query 参数获取 token(用于 img/video/iframe 等无法设置 Header 的场景) + if tokenString == "" { + tokenString = r.URL.Query().Get("token") } - // Token 格式: "Bearer " - tokenString := strings.TrimPrefix(authHeader, "Bearer ") if tokenString == "" { - http.Error(w, "Invalid token format", http.StatusUnauthorized) + http.Error(w, "Unauthorized", http.StatusUnauthorized) return } @@ -41,6 +45,7 @@ func (m *AuthMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc { ctx := context.WithValue(r.Context(), "userId", claims.UserID) ctx = context.WithValue(ctx, "username", claims.Username) ctx = context.WithValue(ctx, "role", claims.Role) + ctx = context.WithValue(ctx, "currentOrgId", claims.CurrentOrgId) // 传递给下一个处理器 next(w, r.WithContext(ctx)) diff --git a/backend/internal/util/jwt/jwt.go b/backend/internal/util/jwt/jwt.go index fe9fccb..4c3c4fe 100644 --- a/backend/internal/util/jwt/jwt.go +++ b/backend/internal/util/jwt/jwt.go @@ -16,18 +16,20 @@ var ( ) type Claims struct { - UserID int64 `json:"userId"` - Username string `json:"username"` - Role string `json:"role"` + UserID int64 `json:"userId"` + Username string `json:"username"` + Role string `json:"role"` + CurrentOrgId int64 `json:"currentOrgId"` jwt.RegisteredClaims } // GenerateToken 生成 JWT Token -func GenerateToken(userId int64, username, role string) (string, error) { +func GenerateToken(userId int64, username, role string, currentOrgId int64) (string, error) { claims := Claims{ - UserID: userId, - Username: username, - Role: role, + UserID: userId, + Username: username, + Role: role, + CurrentOrgId: currentOrgId, RegisteredClaims: jwt.RegisteredClaims{ ExpiresAt: jwt.NewNumericDate(time.Now().Add(TokenExpireTime)), Issuer: "base-api", diff --git a/backend/internal/util/jwt/jwt_test.go b/backend/internal/util/jwt/jwt_test.go index 4604baf..df80a81 100644 --- a/backend/internal/util/jwt/jwt_test.go +++ b/backend/internal/util/jwt/jwt_test.go @@ -8,7 +8,7 @@ import ( ) func TestGenerateToken_ContainsRole(t *testing.T) { - token, err := GenerateToken(1, "testuser", "admin") + token, err := GenerateToken(1, "testuser", "admin", 0) require.NoError(t, err) require.NotEmpty(t, token) @@ -21,7 +21,7 @@ func TestGenerateToken_ContainsRole(t *testing.T) { } func TestGenerateToken_SuperAdminRole(t *testing.T) { - token, err := GenerateToken(99, "admin", "super_admin") + token, err := GenerateToken(99, "admin", "super_admin", 0) require.NoError(t, err) claims, err := ParseToken(token) @@ -30,7 +30,7 @@ func TestGenerateToken_SuperAdminRole(t *testing.T) { } func TestGenerateToken_EmptyRole(t *testing.T) { - token, err := GenerateToken(1, "user", "") + token, err := GenerateToken(1, "user", "", 0) require.NoError(t, err) claims, err := ParseToken(token) diff --git a/backend/model/user_entity.go b/backend/model/user_entity.go index cfe7a3c..0baadba 100644 --- a/backend/model/user_entity.go +++ b/backend/model/user_entity.go @@ -11,6 +11,12 @@ type User struct { Email string `gorm:"column:email;type:varchar(128);not null" json:"email"` Password string `gorm:"column:password;type:varbinary(64);not null" json:"-"` Phone string `gorm:"column:phone;type:varchar(20);default:''" json:"phone"` + CasdoorId string `gorm:"column:casdoor_id;type:varchar(128);default:''" json:"casdoorId"` + UserType string `gorm:"column:user_type;type:varchar(20);default:'local'" json:"userType"` + Role string `gorm:"column:role;type:varchar(20);default:'user'" json:"role"` + Source string `gorm:"column:source;type:varchar(20);default:'register'" json:"source"` + Remark string `gorm:"column:remark;type:varchar(255);default:''" json:"remark"` + CurrentOrgId int64 `gorm:"column:current_org_id;default:0" json:"currentOrgId"` Status int64 `gorm:"column:status;type:tinyint;default:1" json:"status"` CreatedAt time.Time `gorm:"column:created_at;autoCreateTime" json:"createdAt"` UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime" json:"updatedAt"`