feat: JWT 검증 엔드포인트 추가 (POST /api/auth/verify)
All checks were successful
Server CI/CD / deploy (push) Successful in 1m17s
All checks were successful
Server CI/CD / deploy (push) Successful in 1m17s
게임 서버가 클라이언트로부터 받은 JWT를 웹 서버에 전달하면, 서명 검증 + Redis 세션 확인 후 userId와 username을 응답한다. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -92,6 +92,32 @@ func (s *Service) Register(username, password string) error {
|
||||
})
|
||||
}
|
||||
|
||||
// VerifyToken validates a JWT and its Redis session, returning (userID, username, error).
|
||||
func (s *Service) VerifyToken(tokenStr string) (uint, string, error) {
|
||||
token, err := jwt.ParseWithClaims(tokenStr, &Claims{}, func(t *jwt.Token) (any, error) {
|
||||
if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, fmt.Errorf("unexpected signing method")
|
||||
}
|
||||
return []byte(config.C.JWTSecret), nil
|
||||
})
|
||||
if err != nil || !token.Valid {
|
||||
return 0, "", fmt.Errorf("유효하지 않은 토큰입니다")
|
||||
}
|
||||
|
||||
claims, ok := token.Claims.(*Claims)
|
||||
if !ok {
|
||||
return 0, "", fmt.Errorf("토큰 파싱 실패")
|
||||
}
|
||||
|
||||
key := fmt.Sprintf("session:%d", claims.UserID)
|
||||
stored, err := s.rdb.Get(context.Background(), key).Result()
|
||||
if err != nil || stored != tokenStr {
|
||||
return 0, "", fmt.Errorf("만료되었거나 로그아웃된 세션입니다")
|
||||
}
|
||||
|
||||
return claims.UserID, claims.Username, nil
|
||||
}
|
||||
|
||||
func (s *Service) EnsureAdmin(username, password string) error {
|
||||
if _, err := s.repo.FindByUsername(username); err == nil {
|
||||
return nil // 이미 존재하면 스킵
|
||||
|
||||
Reference in New Issue
Block a user