Skip to content
Merged

Dev #258

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 3 additions & 20 deletions backend/app/routers/auth/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
)
from .token_manager import (
clear_auth_cookies,
extract_refresh_token_from_session,
set_auth_cookies,
)

Expand Down Expand Up @@ -72,16 +73,7 @@ def refresh(
db: Session = Depends(get_db),
) -> TokenResponse:
"""リフレッシュトークンで新しいアクセストークンを発行する。"""
# session Cookie に JSON 形式で格納した refresh_token を取り出す
raw = request.cookies.get("session")
token: str | None = None
if raw:
try:
data = _json.loads(raw)
if isinstance(data, dict):
token = data.get("refresh_token")
except (ValueError, TypeError):
pass
token = extract_refresh_token_from_session(request)
if not token:
raise_app_error(
status_code=status.HTTP_401_UNAUTHORIZED,
Expand Down Expand Up @@ -126,16 +118,7 @@ def logout(
"""ログアウト処理。DB の refresh_jti を無効化し Cookie を削除する。
トークン解析が失敗した場合でも必ず Cookie を削除して 204 を返す。
"""
# session Cookie に JSON 形式で格納した refresh_token を取り出す
raw = request.cookies.get("session")
token: str | None = None
if raw:
try:
data = _json.loads(raw)
if isinstance(data, dict):
token = data.get("refresh_token")
except (ValueError, TypeError):
logger.debug("ログアウト時の session Cookie パースに失敗(Cookie 削除を継続)", exc_info=True)
token = extract_refresh_token_from_session(request)
if token:
try:
payload = _decode_token(token)
Expand Down
25 changes: 24 additions & 1 deletion backend/app/routers/auth/token_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
"""

import json
import logging
import secrets

from fastapi import Response
from fastapi import Request, Response
from sqlalchemy.orm import Session

from ...core.security.auth import (
Expand All @@ -17,10 +18,32 @@
from ...core.settings import get_cookie_samesite, get_cookie_secure
from ...repositories import UserRepository

logger = logging.getLogger(__name__)

# 認証セッション Cookie 名(state と redirect_url はフロントの sessionStorage で管理する)
GITHUB_OAUTH_SESSION_COOKIE = "session"


def extract_refresh_token_from_session(request: Request) -> str | None:
"""session Cookie に JSON で格納された refresh_token を取り出す。

refresh と logout の両方で同形のパース処理が必要なため集約する。
Cookie 不在・JSON 不正・型不一致の場合は `None` を返す。
"""
raw = request.cookies.get(GITHUB_OAUTH_SESSION_COOKIE)
if not raw:
return None
try:
data = json.loads(raw)
except (ValueError, TypeError):
logger.debug("session Cookie の JSON パースに失敗", exc_info=True)
return None
if not isinstance(data, dict):
return None
token = data.get("refresh_token")
return token if isinstance(token, str) else None


def set_cookie(response: Response, key: str, value: str, max_age: int) -> None:
"""指定したキーと値で HttpOnly Cookie を設定する。"""
response.set_cookie(
Expand Down
Loading
Loading