refresh token 수정 .
parent
e29e10eb29
commit
bc777ba66c
|
|
@ -291,15 +291,22 @@ def add_exception_handlers(app: FastAPI):
|
||||||
# SocialException 핸들러 추가
|
# SocialException 핸들러 추가
|
||||||
from app.social.exceptions import SocialException
|
from app.social.exceptions import SocialException
|
||||||
|
|
||||||
|
from app.social.exceptions import TokenExpiredError
|
||||||
|
|
||||||
@app.exception_handler(SocialException)
|
@app.exception_handler(SocialException)
|
||||||
def social_exception_handler(request: Request, exc: SocialException) -> Response:
|
def social_exception_handler(request: Request, exc: SocialException) -> Response:
|
||||||
logger.debug(f"Handled SocialException: {exc.__class__.__name__} - {exc.message}")
|
logger.debug(f"Handled SocialException: {exc.__class__.__name__} - {exc.message}")
|
||||||
|
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(
|
return JSONResponse(
|
||||||
status_code=exc.status_code,
|
status_code=exc.status_code,
|
||||||
content={
|
content=content,
|
||||||
"detail": exc.message,
|
|
||||||
"code": exc.code,
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@app.exception_handler(status.HTTP_500_INTERNAL_SERVER_ERROR)
|
@app.exception_handler(status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ class YouTubeOAuthClient(BaseOAuthClient):
|
||||||
"response_type": "code",
|
"response_type": "code",
|
||||||
"scope": " ".join(YOUTUBE_SCOPES),
|
"scope": " ".join(YOUTUBE_SCOPES),
|
||||||
"access_type": "offline", # refresh_token 받기 위해 필요
|
"access_type": "offline", # refresh_token 받기 위해 필요
|
||||||
"prompt": "select_account", # 계정 선택만 표시 (이전 동의 유지)
|
"prompt": "select_account", # 계정 선택만 표시 (동의 화면은 최초 1회만)
|
||||||
"state": state,
|
"state": state,
|
||||||
}
|
}
|
||||||
url = f"{self.AUTHORIZATION_URL}?{urlencode(params)}"
|
url = f"{self.AUTHORIZATION_URL}?{urlencode(params)}"
|
||||||
|
|
|
||||||
|
|
@ -498,34 +498,33 @@ class SocialAccountService:
|
||||||
Raises:
|
Raises:
|
||||||
TokenExpiredError: 토큰 갱신 실패 시 (재연동 필요)
|
TokenExpiredError: 토큰 갱신 실패 시 (재연동 필요)
|
||||||
"""
|
"""
|
||||||
# refresh_token이 없으면 갱신 불가 → 재연동 필요
|
# 만료 시간 확인
|
||||||
if not account.refresh_token:
|
is_expired = False
|
||||||
logger.warning(
|
|
||||||
f"[SOCIAL] refresh_token 없음, 재연동 필요 - account_id: {account.id}"
|
|
||||||
)
|
|
||||||
raise TokenExpiredError(platform=account.platform)
|
|
||||||
|
|
||||||
# 만료 시간 확인 (만료 10분 전이면 갱신, 만료 시간 없어도 갱신 시도)
|
|
||||||
should_refresh = False
|
|
||||||
if account.token_expires_at is None:
|
if account.token_expires_at is None:
|
||||||
logger.info(
|
is_expired = True
|
||||||
f"[SOCIAL] token_expires_at 없음, 갱신 시도 - account_id: {account.id}"
|
|
||||||
)
|
|
||||||
should_refresh = True
|
|
||||||
else:
|
else:
|
||||||
# DB datetime은 naive, now()는 aware이므로 naive로 통일하여 비교
|
|
||||||
current_time = now().replace(tzinfo=None)
|
current_time = now().replace(tzinfo=None)
|
||||||
buffer_time = current_time + timedelta(minutes=10)
|
buffer_time = current_time + timedelta(minutes=10)
|
||||||
if account.token_expires_at <= buffer_time:
|
if account.token_expires_at <= buffer_time:
|
||||||
logger.info(
|
is_expired = True
|
||||||
f"[SOCIAL] 토큰 만료 임박, 갱신 시작 - account_id: {account.id}"
|
|
||||||
)
|
|
||||||
should_refresh = True
|
|
||||||
|
|
||||||
if should_refresh:
|
# 아직 유효하면 그대로 사용
|
||||||
return await self._refresh_account_token(account, session)
|
if not is_expired:
|
||||||
|
return account.access_token
|
||||||
|
|
||||||
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}"
|
||||||
|
)
|
||||||
|
return await self._refresh_account_token(account, session)
|
||||||
|
|
||||||
async def _refresh_account_token(
|
async def _refresh_account_token(
|
||||||
self,
|
self,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue