leaf-library-3/internal/services/auth/auth.go

118 lines
2.7 KiB
Go
Raw Normal View History

2024-12-05 17:44:29 +00:00
package auth
import (
"context"
2024-12-10 10:22:14 +00:00
"leafdev.top/Leaf/leaf-library-3/internal/constants"
"leafdev.top/Leaf/leaf-library-3/internal/dto/user"
errs2 "leafdev.top/Leaf/leaf-library-3/internal/errs"
2024-12-06 15:38:22 +00:00
2024-12-05 17:44:29 +00:00
"github.com/gofiber/fiber/v2"
"github.com/mitchellh/mapstructure"
)
2024-12-06 15:38:22 +00:00
func (a *Service) AuthFromToken(tokenType constants.JwtTokenTypes, token string) (*user.User, error) {
2024-12-05 17:44:29 +00:00
if a.config.Debug.Enabled {
return a.parseUserJWT(tokenType, "")
}
return a.parseUserJWT(tokenType, token)
}
func (a *Service) GetUserFromIdToken(idToken string) (*user.User, error) {
2024-12-06 15:38:22 +00:00
return a.parseUserJWT(constants.JwtTokenTypeIDToken, idToken)
2024-12-05 17:44:29 +00:00
}
func (a *Service) GetUser(ctx *fiber.Ctx) *user.User {
2024-12-06 15:38:22 +00:00
userCtx := ctx.Locals(constants.AuthMiddlewareKey)
2024-12-05 17:44:29 +00:00
u, ok := userCtx.(*user.User)
2024-12-06 18:44:32 +00:00
u.ID = u.Token.Sub
2024-12-05 17:44:29 +00:00
if !ok {
panic("User context is not valid")
}
return u
}
func (a *Service) GetCtx(ctx context.Context) *user.User {
2024-12-06 15:38:22 +00:00
userCtx := ctx.Value(constants.AuthMiddlewareKey)
2024-12-05 17:44:29 +00:00
u, ok := userCtx.(*user.User)
2024-12-06 18:44:32 +00:00
u.ID = u.Token.Sub
2024-12-05 17:44:29 +00:00
if !ok {
panic("User context is not valid")
}
return u
}
func (a *Service) GetUserSafe(ctx *fiber.Ctx) (*user.User, bool) {
2024-12-06 15:38:22 +00:00
userCtx := ctx.Locals(constants.AuthMiddlewareKey)
2024-12-05 17:44:29 +00:00
u, ok := userCtx.(*user.User)
2024-12-06 18:44:32 +00:00
u.ID = u.Token.Sub
2024-12-05 17:44:29 +00:00
return u, ok
}
func (a *Service) GetCtxSafe(ctx context.Context) (*user.User, bool) {
2024-12-06 15:38:22 +00:00
userCtx := ctx.Value(constants.AuthMiddlewareKey)
2024-12-05 17:44:29 +00:00
u, ok := userCtx.(*user.User)
2024-12-06 18:44:32 +00:00
u.ID = u.Token.Sub
2024-12-05 17:44:29 +00:00
return u, ok
}
func (a *Service) SetUser(ctx context.Context, user *user.User) context.Context {
2024-12-06 15:38:22 +00:00
return context.WithValue(ctx, constants.AuthMiddlewareKey, user)
2024-12-05 17:44:29 +00:00
}
2024-12-06 15:38:22 +00:00
func (a *Service) parseUserJWT(tokenType constants.JwtTokenTypes, jwtToken string) (*user.User, error) {
2024-12-10 10:35:45 +00:00
var sub = user.ID(user.AnonymousUser)
2024-12-05 17:44:29 +00:00
var jwtIdToken = new(user.User)
if a.config.Debug.Enabled {
jwtIdToken.Token.Sub = sub
jwtIdToken.Valid = true
return jwtIdToken, nil
} else {
token, err := a.jwks.ParseJWT(jwtToken)
if err != nil {
2024-12-10 10:22:14 +00:00
return nil, errs2.NotValidToken
2024-12-05 17:44:29 +00:00
}
subStr, err := token.Claims.GetSubject()
if err != nil {
2024-12-10 10:22:14 +00:00
return nil, errs2.NotValidToken
2024-12-05 17:44:29 +00:00
}
2024-12-06 18:44:32 +00:00
sub = user.ID(subStr)
2024-12-05 17:44:29 +00:00
// 如果 token.Header 中没有 typ
if token.Header["typ"] == "" {
2024-12-10 10:22:14 +00:00
return nil, errs2.EmptyResponse
2024-12-05 17:44:29 +00:00
}
// 验证 token 类型
if tokenType != "" && tokenType.String() != token.Header["typ"] {
2024-12-10 10:22:14 +00:00
return nil, errs2.TokenError
2024-12-05 17:44:29 +00:00
}
jwtIdToken.Valid = true
err = mapstructure.Decode(token.Claims, &jwtIdToken.Token)
if err != nil {
a.logger.Logger.Error("Failed to map token claims to JwtIDToken struct.\nError: " + err.Error())
return nil, nil
}
// 手动指定,因为 mapstructure 无法转换 UserID 类型
jwtIdToken.Token.Sub = sub
}
return jwtIdToken, nil
}