Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .claude/rules/backend/auth-security.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ paths:
## 認証

- **認証方式**: GitHub OAuth のみ。パスワード認証は実装していない(`users` テーブルにパスワード関連カラムは持たない、OAuth 専用設計)
- **JWT**: `python-jose[cryptography]`、RS256 署名(`JWT_PRIVATE_KEY` / `JWT_PUBLIC_KEY`)
- **JWT**: `PyJWT[crypto]`、RS256 署名(`JWT_PRIVATE_KEY` / `JWT_PUBLIC_KEY`)
- **トークン有効期間**:
- アクセストークン: 15 分(Cookie 名 `access_token`)
- リフレッシュトークン: 7 日(Cookie 名 `refresh_token`)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ GitHub活動分析、ブログ連携による発信力を集計
| AI / LLM | Anthropic Claude / OpenAI GPT / Google Gemini(ユーザー選択式・ADR-0013)、ローカルは Ollama |
| 決済 | Stripe Checkout(クレジット購入・従量課金 / ADR-0012) |
| データベース | Turso (libSQL / SQLite 互換、`sqlalchemy-libsql`) |
| 認証 | JWT Cookie (python-jose), bcrypt, GitHub OAuth |
| 認証 | JWT Cookie (PyJWT), bcrypt, GitHub OAuth |
| 暗号化 | Fernet(フィールド暗号化) |
| PDF出力 | WeasyPrint(職務経歴書), ReportLab(分析レポート補助) |
| インフラ | GCP (Cloud Run, Artifact Registry, Secret Manager), Turso, Cloudflare Pages |
Expand Down
2 changes: 1 addition & 1 deletion THIRD_PARTY_LICENSES.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ DevForge は多くのオープンソースソフトウェア(OSS)に支え
| [pydantic](https://github.com/pydantic/pydantic) | 2.13.4 | MIT |
| [pydyf](https://www.courtbouillon.org/pydyf) | 0.12.1 | BSD License |
| [PyGithub](https://github.com/pygithub/pygithub) | 2.9.1 | GNU Library or Lesser General Public License (LGPL) |
| [PyJWT](https://github.com/jpadilla/pyjwt) | 2.13.0 | MIT |
| [python-dotenv](https://github.com/theskumar/python-dotenv) | 1.2.2 | BSD-3-Clause |
| [python-jose](https://github.com/mpdavis/python-jose) | 3.5.0 | MIT License |
| [python-multipart](https://github.com/Kludex/python-multipart) | 0.0.32 | Apache-2.0 |
| [redis](https://github.com/redis/redis-py) | 8.0.1 | MIT |
| [reportlab](https://www.reportlab.com/) | 5.0.0 | BSD License |
Expand Down
6 changes: 3 additions & 3 deletions backend/app/core/security/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
from datetime import datetime, timedelta, timezone
from typing import NoReturn

import jwt
from fastapi import Depends, Request, status
from jose import JWTError, jwt
from sqlalchemy.orm import Session

from ...db import get_db
Expand Down Expand Up @@ -39,7 +39,7 @@ def validate_jwt_key_pair() -> None:
algorithm=_ALGORITHM,
)
jwt.decode(tok, get_jwt_public_key(), algorithms=[_ALGORITHM])
except JWTError as e:
except jwt.PyJWTError as e:
raise RuntimeError(
f"JWT 鍵ペアが不正です(秘密鍵と公開鍵が一致しないか、フォーマットが壊れています): {e}"
) from e
Expand Down Expand Up @@ -86,7 +86,7 @@ def _decode_token(token: str) -> dict:
"""JWT をデコードしてペイロードを返す。失敗時は 401 を送出する。"""
try:
return jwt.decode(token, get_jwt_public_key(), algorithms=[_ALGORITHM])
except JWTError:
except jwt.PyJWTError:
_raise_auth_failed("jwt_decode_error", with_bearer_header=True)


Expand Down
2 changes: 1 addition & 1 deletion backend/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ python-dotenv==1.2.2
reportlab==5.0.0
google-cloud-storage==3.12.0
pytest==9.1.1
python-jose[cryptography]==3.5.0
PyJWT[crypto]==2.13.0
httpx==0.28.1
# マルチプロバイダ LLM(ADR-0013)。Gemini = google-genai、GPT = openai。
# Gemini / Anthropic は Vertex AI(SA→ADC)経由(ADR-0015)。anthropic[vertex] の
Expand Down
2 changes: 1 addition & 1 deletion backend/tests/auth/test_token_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@

from unittest.mock import AsyncMock, MagicMock, patch

import jwt
import pytest
from app.core.security.auth import (
create_access_token,
create_refresh_token,
)
from app.core.settings import get_cookie_samesite, get_cookie_secure
from app.routers.auth.token_manager import GITHUB_OAUTH_STATE_COOKIE
from jose import jwt

from conftest import _test_public_key, auth_header

Expand Down
Loading