refresh token 수정 .

get_video
hbyang 2026-02-09 16:53:15 +09:00
parent e29e10eb29
commit bc777ba66c
3 changed files with 32 additions and 26 deletions

View File

@ -291,15 +291,22 @@ def add_exception_handlers(app: FastAPI):
# SocialException 핸들러 추가
from app.social.exceptions import SocialException
from app.social.exceptions import TokenExpiredError
@app.exception_handler(SocialException)
def social_exception_handler(request: Request, exc: SocialException) -> Response:
logger.debug(f"Handled SocialException: {exc.__class__.__name__} - {exc.message}")
return JSONResponse(
status_code=exc.status_code,
content={
content = {
"detail": exc.message,
"code": exc.code,
},
}
# TokenExpiredError인 경우 재연동 정보 추가
if isinstance(exc, TokenExpiredError):
content["platform"] = exc.platform
content["reconnect_url"] = f"/social/oauth/{exc.platform}/connect"
return JSONResponse(
status_code=exc.status_code,
content=content,
)
@app.exception_handler(status.HTTP_500_INTERNAL_SERVER_ERROR)

View File

@ -59,7 +59,7 @@ class YouTubeOAuthClient(BaseOAuthClient):
"response_type": "code",
"scope": " ".join(YOUTUBE_SCOPES),
"access_type": "offline", # refresh_token 받기 위해 필요
"prompt": "select_account", # 계정 선택만 표시 (이전 동의 유지)
"prompt": "select_account", # 계정 선택만 표시 (동의 화면은 최초 1회만)
"state": state,
}
url = f"{self.AUTHORIZATION_URL}?{urlencode(params)}"

View File

@ -498,35 +498,34 @@ class SocialAccountService:
Raises:
TokenExpiredError: 토큰 갱신 실패 (재연동 필요)
"""
# refresh_token이 없으면 갱신 불가 → 재연동 필요
if not account.refresh_token:
logger.warning(
f"[SOCIAL] refresh_token 없음, 재연동 필요 - account_id: {account.id}"
)
raise TokenExpiredError(platform=account.platform)
# 만료 시간 확인 (만료 10분 전이면 갱신, 만료 시간 없어도 갱신 시도)
should_refresh = False
# 만료 시간 확인
is_expired = False
if account.token_expires_at is None:
logger.info(
f"[SOCIAL] token_expires_at 없음, 갱신 시도 - account_id: {account.id}"
)
should_refresh = True
is_expired = True
else:
# DB datetime은 naive, now()는 aware이므로 naive로 통일하여 비교
current_time = now().replace(tzinfo=None)
buffer_time = current_time + timedelta(minutes=10)
if account.token_expires_at <= buffer_time:
is_expired = True
# 아직 유효하면 그대로 사용
if not is_expired:
return account.access_token
# 만료됐는데 refresh_token이 없으면 재연동 필요
if not account.refresh_token:
logger.warning(
f"[SOCIAL] access_token 만료 + refresh_token 없음, 재연동 필요 - "
f"account_id: {account.id}"
)
raise TokenExpiredError(platform=account.platform)
# refresh_token으로 갱신
logger.info(
f"[SOCIAL] 토큰 만료 임박, 갱신 시작 - account_id: {account.id}"
)
should_refresh = True
if should_refresh:
return await self._refresh_account_token(account, session)
return account.access_token
async def _refresh_account_token(
self,
account: SocialAccount,