OAuth 2.1 / OIDC ドキュメント
KOKONATSU ACCOUNTの OAuth 2.1 認可機能について説明します
概要
KOKONATSU ACCOUNTは OAuth 2.1 および OpenID Connect に対応した認証・認可サービスです。 連携アプリケーションは以下の機能を利用できます。
- OAuth 2.1 認可コードフロー + PKCE (S256)
- OpenID Connect (OIDC) による ID トークン
- アクセストークンによる Userinfo エンドポイントへのアクセス
- リフレッシュトークンによる長期的なアクセス維持
アプリケーションの登録
アプリケーションを連携するには、まずクライアントを登録してください。
- アカウントページから OAuth アプリ管理 に移動
- 「新規クライアント」で名前とリダイレクト URI を入力して登録
- 発行された
client_idとclient_secretを安全に保管
client_secret は登録時にのみ表示されます。紛失した場合はクライアント設定から再発行してください。
認可コードフロー(PKCE)
KOKONATSU ACCOUNTは OAuth 2.1 に準拠し、PKCE (S256) を必須としています。
Step 1: PKCE コードベリファイアとチャレンジを生成
暗号学的に安全なランダム文字列(code_verifier)を生成し、その SHA-256 ハッシュを base64url エンコードした code_challenge を作成します。
// 例 (Node.js)
const crypto = require("crypto");
const verifier = crypto.randomBytes(32).toString("base64url");
const challenge = crypto
.createHash("sha256")
.update(verifier)
.digest("base64url")
.replace(/=/g, "");
Step 2: 認可エンドポイントへリダイレクト
ユーザーを以下の URL にリダイレクトします。
https://account.kokonatsu.net/oauth/authorize?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=openid%20profile%20email&code_challenge_method=S256&code_challenge=YOUR_CODE_CHALLENGE&state=YOUR_STATE
Step 3: 認可コードを受け取る
ユーザーが同意すると、登録されたリダイレクト URI に認可コードが付与されてリダイレクトされます。
GET https://account.kokonatsu.net/your/callback?code=AUTH_CODE&state=YOUR_STATE
Step 4: トークンエンドポイントに POST
認可コードをアクセストークンと交換します。
POST https://account.kokonatsu.net/api/oauth/token Content-Type: application/x-www-form-urlencoded grant_type=authorization_code& code=AUTH_CODE& redirect_uri=YOUR_REDIRECT_URI& client_id=YOUR_CLIENT_ID& client_secret=YOUR_CLIENT_SECRET& code_verifier=YOUR_CODE_VERIFIER
レスポンス:
{
"access_token": "eyJ...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "...",
"scope": "openid profile email",
"id_token": "eyJ..." // openid scope を含めた場合のみ
}スコープ一覧
OpenID Connect を使用する場合に必須。sub(ユーザーID)を含む ID トークンを発行します。
ユーザーの表示名(name)・プロフィール情報・アバター画像 URL へのアクセスを許可します。
ユーザーのメールアドレスへのアクセスを許可します。
アクセストークン期限切れ後にリフレッシュトークンを使用して新しいアクセストークンを取得することを許可します。
ユーザーが連携している外部アカウント(Discord・Google 等)のプロバイダ名と識別子を取得します。
エンドポイント一覧
/oauth/authorize
認可リクエスト(ユーザーをリダイレクト)
/api/oauth/token
トークンエンドポイント(認可コード・リフレッシュトークンの交換)
/api/oauth/userinfo
Userinfo エンドポイント(Bearer トークンでユーザー情報取得)
/api/oauth/introspect
トークンイントロスペクション(RFC 7662)
/api/oauth/revoke
トークン失効(RFC 7009)
/api/oauth/clients
OAuth クライアント登録
/.well-known/openid-configuration
OpenID Connect ディスカバリー
/.well-known/oauth-authorization-server
OAuth 2.0 認可サーバーメタデータ(RFC 8414)
/.well-known/jwks.json
JWT 公開鍵(JWKS)
Userinfo エンドポイント
アクセストークンを Bearer 認証で送信することで、認可されたユーザー情報を取得できます。 取得できる情報はトークンに付与されたスコープによって異なります。
GET https://account.kokonatsu.net/api/oauth/userinfo Authorization: Bearer YOUR_ACCESS_TOKEN
レスポンス(スコープによって項目が変化):
{
"sub": "user-uuid", // 常に含まれる
"email": "user@example.com", // email スコープ
"name": "ユーザー名", // profile スコープ
"picture": "https://...", // profile スコープ
"linked_accounts": [ // linked スコープ
{ "provider": "discord", "subject": "12345", "connected_at": "..." },
{ "provider": "google", "subject": "67890", "connected_at": "..." }
]
}OpenID Connect
openid スコープを含めると、ID トークン(JWT)が発行されます。 ID トークンはクライアント側で検証可能なユーザー情報を含みます。
ID トークンの検証:
- 署名アルゴリズム: HS256 または RS256(OIDC_PRIVATE_KEY 設定時)
- 発行者(iss):
https://account.kokonatsu.net - 対象者(aud): クライアントの client_id
- nonce 検証(指定された場合)
リフレッシュトークン
offline_access スコープを付与すると、アクセストークン(1時間有効)の期限切れ後に リフレッシュトークンを使用して新しいアクセストークンを取得できます。
POST https://account.kokonatsu.net/api/oauth/token Content-Type: application/x-www-form-urlencoded grant_type=refresh_token& refresh_token=YOUR_REFRESH_TOKEN& client_id=YOUR_CLIENT_ID& client_secret=YOUR_CLIENT_SECRET
リフレッシュトークンは発行から30日間有効です。 リフレッシュトークンが使用されるたびに古いトークンは無効化され、新しいトークンが発行されます。 過去に使用済みのリフレッシュトークンが再利用された場合、トークン盗難とみなされ、 該当ユーザー+クライアントの全てのトークンが無効化されます(OAuth 2.1 §4.12.2)。
エラーレスポンス
エラー時は以下の形式で JSON が返却されます。
{
"error": "invalid_grant",
"error_description": "認可コードが無効です。"
}主なエラーコード:
invalid_requestリクエストパラメータが不足または不正
invalid_clientclient_id / client_secret が無効
invalid_grant認可コードまたはリフレッシュトークンが無効または期限切れ
unauthorized_clientクライアントに権限がない
access_deniedユーザーが同意を拒否
too_many_requestsレート制限超過