1
0
forked from baron/baron-sso

토큰 8자리

This commit is contained in:
2026-01-13 10:24:13 +09:00
parent b5aed4fedc
commit ee9f835ceb

View File

@@ -4,6 +4,8 @@ import (
"baron-sso-backend/internal/domain"
"baron-sso-backend/internal/service"
"context"
crand "crypto/rand"
"encoding/hex"
"encoding/json"
"fmt"
"log"
@@ -24,6 +26,15 @@ type AuthHandler struct {
DescopeClient *client.DescopeClient
}
// Helper to generate secure random strings
func generateSecureToken(length int) string {
b := make([]byte, length)
if _, err := crand.Read(b); err != nil {
return ""
}
return hex.EncodeToString(b)
}
func NewAuthHandler() *AuthHandler {
redisService, err := service.NewRedisService()
if err != nil {
@@ -108,10 +119,9 @@ func (h *AuthHandler) InitEnchantedLink(c *fiber.Ctx) error {
loginID := strings.ReplaceAll(req.LoginID, "-", "")
loginID = strings.ReplaceAll(loginID, " ", "")
// Generate tokens
rand.Seed(time.Now().UnixNano())
token := fmt.Sprintf("tk_%d%d", time.Now().Unix(), rand.Intn(100000))
pendingRef := fmt.Sprintf("ref_%d%d", time.Now().Unix(), rand.Intn(100000))
// Generate secure tokens
token := generateSecureToken(4)
pendingRef := generateSecureToken(4)
// Store in Redis
h.RedisService.Set("enchanted_session:"+pendingRef, `{"status":"pending"}`, 5*time.Minute)
@@ -177,7 +187,7 @@ func (h *AuthHandler) VerifyMagicLink(c *fiber.Ctx) error {
}
var tokenData map[string]string
json.Unmarshal([]byte(val), &tokenData)
json.Unmarshal([]byte(val), &data := tokenData)
pendingRef := tokenData["pendingRef"]
loginID := tokenData["loginId"]
@@ -186,10 +196,9 @@ func (h *AuthHandler) VerifyMagicLink(c *fiber.Ctx) error {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Descope Client not configured"})
}
// Use GenerateEmbeddedLink to get a session JWT directly for the user.
// This generates a JWT that mimics a successful login.
// In the Go SDK, GenerateEmbeddedLink usually returns the token string directly.
jwtToken, err := h.DescopeClient.Management.User().GenerateEmbeddedLink(context.Background(), loginID, nil, 0)
// Use GenerateEmbeddedLink to get a temporary token directly for the user.
// This generates a token that will be exchanged for a real session.
embeddedToken, err := h.DescopeClient.Management.User().GenerateEmbeddedLink(context.Background(), loginID, nil, 0)
if err != nil {
// If user does not exist, create it and retry
if strings.Contains(err.Error(), "User not found") || strings.Contains(err.Error(), "E062108") {
@@ -203,7 +212,6 @@ func (h *AuthHandler) VerifyMagicLink(c *fiber.Ctx) error {
userObj.Email = loginID
} else {
// LoginID is likely a phone number
// Convert 010-XXXX-XXXX (sanitized to 010XXXXXXXX) to +8210XXXXXXXX
if strings.HasPrefix(loginID, "010") {
descopeLoginID = "+82" + loginID[1:]
}
@@ -217,8 +225,8 @@ func (h *AuthHandler) VerifyMagicLink(c *fiber.Ctx) error {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Failed to create new user"})
}
// Retry generating token with the Descope LoginID
jwtToken, err = h.DescopeClient.Management.User().GenerateEmbeddedLink(context.Background(), descopeLoginID, nil, 0)
// Retry generating embedded token with the Descope LoginID
embeddedToken, err = h.DescopeClient.Management.User().GenerateEmbeddedLink(context.Background(), descopeLoginID, nil, 0)
if err != nil {
log.Printf("Failed to generate Descope Session after creation: %v", err)
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Failed to generate token for new user"})
@@ -229,24 +237,23 @@ func (h *AuthHandler) VerifyMagicLink(c *fiber.Ctx) error {
}
}
// Exchange the Embedded Token for a real Session JWT
// We pass nil for ResponseWriter as we don't need the SDK to set cookies here.
authInfo, err := h.DescopeClient.Auth.MagicLink().Verify(context.Background(), jwtToken, nil)
// Exchange the Embedded Token for a real User Session JWT
authInfo, err := h.DescopeClient.Auth.MagicLink().Verify(context.Background(), embeddedToken, nil)
if err != nil {
log.Printf("Failed to verify embedded token: %v", err)
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Failed to verify upstream token"})
}
realJwtToken := authInfo.SessionToken.JWT
sessionToken := authInfo.SessionToken.JWT
// Update Session
// Update Session in Redis for the polling client
sessionData, _ := json.Marshal(map[string]string{
"status": "success",
"jwt": realJwtToken,
"jwt": sessionToken,
})
h.RedisService.Set("enchanted_session:"+pendingRef, string(sessionData), 5*time.Minute)
return c.JSON(fiber.Map{
"token": realJwtToken,
"token": sessionToken,
"message": "Login successful",
})
}
@@ -330,4 +337,4 @@ func (h *AuthHandler) HandleDescopeEmailRelay(c *fiber.Ctx) error {
// You would need an SMTP service here if you route ALL emails through this relay.
log.Printf("[Email Webhook] Real email skipped (Not implemented): %s", req.To)
return c.Status(501).JSON(fiber.Map{"error": "Real email sending not implemented"})
}
}