forked from baron/baron-sso
gateway 분리 아키텍처
This commit is contained in:
@@ -74,6 +74,7 @@ type AuthHandler struct {
|
||||
EmailService domain.EmailService
|
||||
RedisService *service.RedisService
|
||||
DescopeClient *client.DescopeClient
|
||||
KratosAdmin *service.KratosAdminService
|
||||
IdpProvider domain.IdentityProvider
|
||||
AuditRepo domain.AuditRepository
|
||||
Hydra *service.HydraAdminService
|
||||
@@ -156,6 +157,7 @@ func NewAuthHandler(redisService *service.RedisService, idpProvider domain.Ident
|
||||
EmailService: service.NewEmailService(),
|
||||
RedisService: redisService,
|
||||
DescopeClient: descopeClient,
|
||||
KratosAdmin: service.NewKratosAdminService(),
|
||||
IdpProvider: idpProvider,
|
||||
AuditRepo: auditRepo,
|
||||
Hydra: service.NewHydraAdminService(),
|
||||
@@ -823,13 +825,20 @@ func (h *AuthHandler) VerifyMagicLink(c *fiber.Ctx) error {
|
||||
sessionToken := authInfo.SessionToken.JWT
|
||||
c.Locals("login_id", loginID)
|
||||
setSessionIDLocal(c, authInfo.SessionToken)
|
||||
sessionID := extractSessionIDFromToken(authInfo.SessionToken)
|
||||
|
||||
slog.Info("[Verify] Success! Updating Redis session", "pendingRef", pendingRef)
|
||||
sessionData, _ := json.Marshal(map[string]string{
|
||||
sessionData := map[string]string{
|
||||
"status": statusSuccess,
|
||||
"jwt": sessionToken,
|
||||
})
|
||||
h.RedisService.Set(prefixSession+pendingRef, string(sessionData), defaultExpiration)
|
||||
}
|
||||
if sessionID != "" {
|
||||
sessionData["session_id"] = sessionID
|
||||
}
|
||||
sessionDataJSON, _ := json.Marshal(sessionData)
|
||||
h.RedisService.Set(prefixSession+pendingRef, string(sessionDataJSON), defaultExpiration)
|
||||
|
||||
h.writeLinkAuditLog(loginID, pendingRef, authInfo.SessionToken, c)
|
||||
|
||||
return c.JSON(fiber.Map{
|
||||
"token": sessionToken,
|
||||
@@ -2226,6 +2235,43 @@ func (h *AuthHandler) writeQrAuditLog(loginID, pendingRef string, sessionToken *
|
||||
_ = h.AuditRepo.Create(log)
|
||||
}
|
||||
|
||||
func (h *AuthHandler) writeLinkAuditLog(loginID, pendingRef string, sessionToken *domain.Token, c *fiber.Ctx) {
|
||||
if h.AuditRepo == nil {
|
||||
return
|
||||
}
|
||||
meta := qrMeta{
|
||||
IPAddress: extractClientIPFromHeaders(c),
|
||||
UserAgent: "",
|
||||
}
|
||||
if c != nil {
|
||||
meta.UserAgent = c.Get("User-Agent")
|
||||
}
|
||||
sessionID := extractSessionIDFromToken(sessionToken)
|
||||
details := map[string]any{
|
||||
"path": "/api/v1/auth/magic-link/verify",
|
||||
"login_id": loginID,
|
||||
"pending_ref": pendingRef,
|
||||
}
|
||||
if sessionID != "" {
|
||||
details["session_id"] = sessionID
|
||||
}
|
||||
detailsJSON, _ := json.Marshal(details)
|
||||
|
||||
log := &domain.AuditLog{
|
||||
EventID: GenerateSecureToken(16),
|
||||
Timestamp: time.Now(),
|
||||
UserID: "",
|
||||
SessionID: sessionID,
|
||||
EventType: "POST /api/v1/auth/magic-link/verify",
|
||||
Status: "success",
|
||||
IPAddress: meta.IPAddress,
|
||||
UserAgent: meta.UserAgent,
|
||||
Details: string(detailsJSON),
|
||||
AuthMethod: "링크",
|
||||
}
|
||||
_ = h.AuditRepo.Create(log)
|
||||
}
|
||||
|
||||
func extractClientIPFromHeaders(c *fiber.Ctx) string {
|
||||
if c == nil {
|
||||
return ""
|
||||
@@ -2451,6 +2497,26 @@ func (h *AuthHandler) resolveCurrentProfile(c *fiber.Ctx) (*domain.UserProfileRe
|
||||
func (h *AuthHandler) resolveConsentSubject(c *fiber.Ctx) (string, error) {
|
||||
token := h.getBearerToken(c)
|
||||
if token != "" {
|
||||
if looksLikeJWT(token) && h.DescopeClient != nil && h.KratosAdmin != nil {
|
||||
authorized, userToken, err := h.DescopeClient.Auth.ValidateSessionWithToken(c.Context(), token)
|
||||
if err == nil && authorized {
|
||||
userResponse, loadErr := h.DescopeClient.Management.User().Load(c.Context(), userToken.ID)
|
||||
if loadErr == nil {
|
||||
if email := strings.TrimSpace(userResponse.Email); email != "" {
|
||||
if identityID, err := h.KratosAdmin.FindIdentityIDByIdentifier(c.Context(), email); err == nil && identityID != "" {
|
||||
return identityID, nil
|
||||
}
|
||||
}
|
||||
if phone := strings.TrimSpace(userResponse.Phone); phone != "" {
|
||||
normalized := normalizePhoneForLoginID(phone)
|
||||
if identityID, err := h.KratosAdmin.FindIdentityIDByIdentifier(c.Context(), normalized); err == nil && identityID != "" {
|
||||
return identityID, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return userToken.ID, nil
|
||||
}
|
||||
}
|
||||
return h.resolveIdentityID(c, token)
|
||||
}
|
||||
cookie := c.Get("Cookie")
|
||||
|
||||
Reference in New Issue
Block a user