認証 API
Google OAuth 2.0 によるログインと JWT の発行・更新。共通規約は API 共通仕様 を参照。
ベースパス: /api/v1/auth
| メソッド | パス | 概要 | 認証 |
|---|---|---|---|
| GET | /google |
Google OAuth 開始 | 不要 |
| GET | /google/callback |
Google OAuth コールバック | 不要 |
| POST | /refresh |
アクセストークン更新 | 不要(リフレッシュトークンで認証) |
| POST | /logout |
ログアウト | 必要 |
| GET | /me |
現在のユーザー情報取得 | 必要 |
Google OAuth 開始
URI
リクエスト
パラメータなし。
レスポンス(302 Found)
Google の認可画面へリダイレクトする。ボディはない。
Note
Swagger UI から実行する場合はリダイレクトが追えないため、新しいタブでこの URL を直接開く。
Google OAuth コールバック
Google からのリダイレクトを受け取り、認可コードをトークンに交換してユーザーを作成/更新し、フロントエンドへ戻す。
URI
クエリパラメータ
| フィールド | 必須 | ルール |
|---|---|---|
code |
◯ | OAuth 認可コード。1 文字以上 |
state |
- | OAuth の state パラメータ |
レスポンス(302 Found)
| ケース | リダイレクト先 |
|---|---|
| 成功 | {FRONTEND_URL}/login?token={accessToken} |
| 失敗 | {FRONTEND_URL}/login?error=auth_failed |
失敗時も 302 で返り、内部エラーの詳細は URL に含めない(ログにのみ記録される)。
例外処理
| 説明 | ステータスコード | ステータス名 |
|---|---|---|
code の欠落・形式不正 |
400 | Bad Request |
処理フロー
sequenceDiagram
participant G as Google
participant API as Backend API
participant DB as PostgreSQL
participant FE as フロントエンド
G->>API: GET /google/callback?code=...
API->>G: code をアクセストークンに交換
G-->>API: プロフィール(google_id / email / name / picture)
API->>DB: google_id でユーザー検索
alt 未登録
API->>DB: users を作成(role = member)
else 登録済み
API->>DB: プロフィールを更新
end
API->>API: JWT を署名(HS256)
API-->>FE: 302 {FRONTEND_URL}/login?token=...
アクセストークン更新
URI
リクエストボディ
リクエストボディは JSON です。
バリデーションルール
| フィールド | ルール |
|---|---|
refreshToken |
必須。1 文字以上 |
レスポンス(200 OK)
{
"success": true,
"status": "success",
"statusCode": 200,
"timestamp": "2026-01-15T10:00:00.000Z",
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "refresh_token_here",
"expiresIn": 3600
},
"path": "/api/v1/auth/refresh",
"method": "POST"
}
例外処理
| 説明 | ステータスコード | ステータス名 |
|---|---|---|
| ボディの形式不正 | 400 | Bad Request |
| リフレッシュトークンが無効/期限切れ | 401 | Unauthorized |
ログアウト
URI
認証要件
Authorization: Bearer <access_token> が必要。
レスポンス(200 OK)
{
"success": true,
"status": "success",
"statusCode": 200,
"data": { "message": "Logged out successfully" },
"path": "/api/v1/auth/logout",
"method": "POST"
}
例外処理
| 説明 | ステータスコード | ステータス名 |
|---|---|---|
| トークンが欠落または無効 | 401 | Unauthorized |
サーバ側でトークンを無効化しない
ステートレス JWT のため、ログアウトはクライアント側でトークンを破棄することで成立する。このエンドポイントはブラックリスト登録などを行わないため、発行済みトークンは期限まで有効。
現在のユーザー情報取得
URI
認証要件
Authorization: Bearer <access_token> が必要。
レスポンス(200 OK)
{
"success": true,
"status": "success",
"statusCode": 200,
"data": {
"id": 1,
"email": "user@example.com",
"name": "John Doe",
"picture": "https://example.com/avatar.jpg",
"role": "member",
"createdAt": "2026-01-15T09:00:00Z"
},
"path": "/api/v1/auth/me",
"method": "GET"
}
| フィールド | 型 | 説明 |
|---|---|---|
id |
integer | ユーザー ID |
email |
string | メールアドレス |
name |
string | 表示名 |
picture |
string | null | プロフィール画像 URL(DB 上は avatar_url) |
role |
enum | admin / member / viewer |
createdAt |
string(date-time) | 登録日時 |
例外処理
| 説明 | ステータスコード | ステータス名 |
|---|---|---|
| トークンが欠落または無効 | 401 | Unauthorized |