add kakao_verify endpoint for kakao login at frontend side

insta
Dohyun Lim 2026-01-21 08:53:16 +09:00
parent b4e5d04dbb
commit 36de908431
3 changed files with 53 additions and 4 deletions

View File

@ -15,6 +15,7 @@ from app.user.dependencies import get_current_user
from app.user.models import User from app.user.models import User
from app.user.schemas.user_schema import ( from app.user.schemas.user_schema import (
AccessTokenResponse, AccessTokenResponse,
KakaoCodeRequest,
KakaoLoginResponse, KakaoLoginResponse,
LoginResponse, LoginResponse,
RefreshTokenRequest, RefreshTokenRequest,
@ -78,6 +79,54 @@ async def kakao_callback(
) )
@router.post(
"/kakao/verify",
response_model=LoginResponse,
summary="카카오 인가 코드 검증 및 토큰 발급",
description="""
프론트엔드에서 카카오 로그인 받은 인가 코드를 검증하고 JWT 토큰을 발급합니다.
## 사용 시나리오
1. 프론트엔드가 카카오 로그인 완료 인가 코드(code) 받음
2. 프론트엔드가 엔드포인트에 code를 POST로 전달
3. 서버가 카카오 서버에 code 검증 사용자 정보 조회
4. JWT 토큰 발급 사용자 정보 반환
## 응답
- 신규 사용자인 경우 `user.is_new_user` `true` 반환됩니다.
- `redirect_url` 로그인 이동할 프론트엔드 URL입니다.
""",
)
async def kakao_verify(
request: Request,
body: KakaoCodeRequest,
session: AsyncSession = Depends(get_session),
user_agent: Optional[str] = Header(None, alias="User-Agent"),
) -> LoginResponse:
"""
카카오 인가 코드 검증 토큰 발급
프론트엔드가 카카오 콜백에서 받은 인가 코드를 전달하면
카카오 서버에서 검증 JWT 토큰을 발급합니다.
신규 사용자인 경우 자동으로 회원가입이 처리됩니다.
"""
# 클라이언트 IP 추출
ip_address = request.client.host if request.client else None
# X-Forwarded-For 헤더 확인 (프록시/로드밸런서 뒤에 있는 경우)
forwarded_for = request.headers.get("X-Forwarded-For")
if forwarded_for:
ip_address = forwarded_for.split(",")[0].strip()
return await auth_service.kakao_login(
code=body.code,
session=session,
user_agent=user_agent,
ip_address=ip_address,
)
@router.post( @router.post(
"/refresh", "/refresh",
response_model=AccessTokenResponse, response_model=AccessTokenResponse,

View File

@ -1,6 +1,6 @@
from app.user.schemas.user_schema import ( from app.user.schemas.user_schema import (
AccessTokenResponse, AccessTokenResponse,
KakaoCallbackRequest, KakaoCodeRequest,
KakaoLoginResponse, KakaoLoginResponse,
KakaoTokenResponse, KakaoTokenResponse,
KakaoUserInfo, KakaoUserInfo,
@ -13,7 +13,7 @@ from app.user.schemas.user_schema import (
__all__ = [ __all__ = [
"AccessTokenResponse", "AccessTokenResponse",
"KakaoCallbackRequest", "KakaoCodeRequest",
"KakaoLoginResponse", "KakaoLoginResponse",
"KakaoTokenResponse", "KakaoTokenResponse",
"KakaoUserInfo", "KakaoUserInfo",

View File

@ -27,8 +27,8 @@ class KakaoLoginResponse(BaseModel):
} }
class KakaoCallbackRequest(BaseModel): class KakaoCodeRequest(BaseModel):
"""카카오 콜백 요청 (인가 코드)""" """카카오 인가 코드 검증 요청 (프론트엔드에서 전달)"""
code: str = Field(..., min_length=1, description="카카오 인가 코드") code: str = Field(..., min_length=1, description="카카오 인가 코드")