1. OAuth クライアントを作成する
デベロッパーポータルのダッシュボードからアプリケーションを作成し、発行された Client ID と Client Secret を保存します。必要なリダイレクト URI、CORS オリジン、スコープを設定してください。
Developer Documentation
デベロッパーポータルで認証情報を発行し、API ドキュメントでエンドポイントを確認し、サンプルアプリで実装を検証したうえで、準備ができたら Vercel にデプロイします。
デベロッパーポータルのダッシュボードからアプリケーションを作成し、発行された Client ID と Client Secret を保存します。必要なリダイレクト URI、CORS オリジン、スコープを設定してください。
Swagger の API ドキュメントでエンドポイント、リクエストスキーマ、サンプル payload を確認します。まずは認証方式と、利用するリソースに必要なリクエスト形式を把握してください。
サンプルリポジトリには、連携フローを一通り確認できる実装例があります。環境変数、コールバック URL、トークン処理の確認に最も手早く使えます。
サンプルリポジトリを見る →ローカルで動作確認できたら Vercel にデプロイします。本番環境の OAuth フローが成立するよう、デベロッパーポータル側のリダイレクト URI も本番 URL に更新してください。
Client Secret はサーバー側で扱う秘密情報です。ブラウザ向けコードや公開リポジトリに含めないでください。
このポータルの各設定項目に関する技術的なリファレンスです。
サーバーサイドアプリケーションおよびSPAに推奨されるフローです。
authorization_codeRecommended標準的なサーバーサイドまたはPKCEフロー。ユーザーがプロバイダーで認証し、サーバーが返ってきたコードをトークンと交換します。ほぼすべてのアプリケーションに推奨です。
refresh_tokenCommonユーザーに再度ログインを求めずにアクセストークンを更新できます。初回の認可リクエスト時に offline_access スコープが必要です。
client_credentialsComing soonユーザー操作なしのマシン間認証(M2M)。サーバーが自身の認証情報をトークンエンドポイントに直接送信します。(近日公開予定)
codeRecommendedリダイレクトURLに認可コードを返します。authorization_code グラントと必ずセットで使います。推奨オプションです。
code id_tokenAdvancedリダイレクトに認可コードとIDトークンの両方を返します。サーバーでコード交換する前にユーザー情報を検証したい場合に便利です。
client_secret_basicRecommendedclient_id と client_secret を HTTP Basic Auth ヘッダー(Base64エンコード)で送信します。最も広くサポートされている推奨のデフォルト方式です。
client_secret_postAlternativeヘッダーではなくPOSTボディに client_id と client_secret フィールドとして送信します。Basic Auth に対応していないサーバーで使います。
none (PKCE)Public clientsクライアントシークレット不要。代わりにPKCE(Proof Key for Code Exchange)を使います。シークレットを安全に保管できないSPAやモバイルアプリ向けです。
認可コードを受け取ったあと、サーバーからトークンエンドポイントにPOSTします。
リクエスト
POST /oauth2/token HTTP/1.1
Host: auth.bravefrontierheroes.com
Authorization: Basic base64(CLIENT_ID:CLIENT_SECRET)
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=AUTH_CODE_HERE
&redirect_uri=https://yourapp.com/callbackレスポンス
{
"access_token": "eyJhbGciOiJSUzI1NiJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "ory_rt_abc123...",
"scope": "openid profile email offline_access",
"id_token": "eyJhbGciOiJSUzI1NiJ9..."
}保存しておいたリフレッシュトークンでユーザー操作なしに新しいアクセストークンを取得します。
リクエスト
POST /oauth2/token HTTP/1.1
Host: auth.bravefrontierheroes.com
Authorization: Basic base64(CLIENT_ID:CLIENT_SECRET)
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token
&refresh_token=ory_rt_abc123...レスポンス
{
"access_token": "eyJhbGciOiJSUzI1NiJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "ory_rt_xyz789...",
"scope": "openid profile email offline_access"
}保護されたエンドポイントへのリクエストには必ずアクセストークンをBearerトークンとして含めます。
リクエスト
GET /v1/some-protected-resource HTTP/1.1
Host: api.bravefrontierheroes.com
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...レスポンス
HTTP/1.1 200 OK
Content-Type: application/json
{
"data": { ... }
}リフレッシュトークンでユーザーを継続認証する方法。
デフォルトではアクセストークンの有効期限は1時間です。ユーザーに再ログインを求めずに自動的に再認証するには、refresh_token グラントと offline_access スコープを使用するようにクライアントを設定します。
ユーザーを認可エンドポイントにリダイレクトする際、scope パラメータに offline_access を追加します。これにより認可サーバーはアクセストークンと同時にリフレッシュトークンを発行します。
# Redirect the user to:
https://auth.bravefrontierheroes.com/oauth2/auth
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https://yourapp.com/callback
&scope=openid+profile+offline_access
&state=RANDOM_STATE認可コード交換後、トークンエンドポイントのレスポンスに refresh_token フィールドが含まれます。サーバー側で安全に保管し、ブラウザには絶対に公開しないでください。
レスポンス
{
"access_token": "eyJhbGciOiJSUzI1NiJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "ory_rt_abc123...",
"scope": "openid profile email offline_access",
"id_token": "eyJhbGciOiJSUzI1NiJ9..."
}アクセストークンが期限切れになった場合(または 401 レスポンスを受け取った場合)、保存しておいたリフレッシュトークンをトークンエンドポイントにPOSTして新しいアクセストークンを無操作で取得します。
リクエスト
POST /oauth2/token HTTP/1.1
Host: auth.bravefrontierheroes.com
Authorization: Basic base64(CLIENT_ID:CLIENT_SECRET)
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token
&refresh_token=ory_rt_abc123...レスポンス
{
"access_token": "eyJhbGciOiJSUzI1NiJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "ory_rt_xyz789...",
"scope": "openid profile email offline_access"
}リフレッシュトークンは長期有効な認証情報です。サーバーサイドのセッションやデータベースに暗号化して保存してください。localStorage・JavaScriptからアクセス可能なCookie・ソースコードリポジトリには絶対に保存しないでください。
以下のプロンプトをClaudeやChatGPTに貼り付けると、連携の骨格を素早く生成できます。
サーバーサイドセッションとhttpOnlyクッキーを使ったAuthorization Codeフロー。
BFH OAuth2 プロバイダーと連携する Next.js 16 App Router アプリケーションを作成してください。 技術スタック: TypeScript、Tailwind CSS、iron-session(httpOnlyクッキーセッション) OAuth2 設定: - 認可エンドポイント: https://auth.bravefrontierheroes.com/oauth2/auth - トークンエンドポイント: https://auth.bravefrontierheroes.com/oauth2/token - Client ID: YOUR_CLIENT_ID - Client Secret: YOUR_CLIENT_SECRET(サーバーサイドのみ、ブラウザに公開しないこと) - リダイレクトURI: http://localhost:3000/callback - スコープ: openid profile email offline_access 必要なルート: 1. GET / — 「BFHでサインイン」ボタンのログインページ 2. GET /api/auth/login — ランダムなstateを生成してクッキーに保存し、認可エンドポイントにリダイレクト 3. GET /callback — code+state パラメータで /api/auth/callback を呼ぶクライアントコンポーネント 4. POST /api/auth/callback — stateを検証し、コードをトークンと交換してセッションを保存 5. GET /dashboard — 保護ページ。未認証なら / にリダイレクト 6. GET /api/auth/logout — セッションクッキーを削除して / にリダイレクト セッション構造: accessToken(string)、refreshToken(string)、expiresAt(number) 自動リフレッシュ: expiresAt < Date.now() + 60000 の場合、リクエスト前にリフレッシュする。 認証後、JWTをデコードして sub と wallet_address クレームを取り出し、ダッシュボードに表示する。
Bearerトークンを保護ルートで検証するNode.jsバックエンド。
BFH OAuth2 プロバイダーが発行した Bearer JWT アクセストークンを検証する Node.js + Express REST API を作成してください。 技術スタック: TypeScript、express、jose(JWT/JWKS)、cors、dotenv 設定(.envから読み込み): - JWKS_URI=https://auth.bravefrontierheroes.com/.well-known/jwks.json - EXPECTED_ISSUER=https://auth.bravefrontierheroes.com/ - EXPECTED_AUDIENCE=YOUR_CLIENT_ID - PORT=4000 ルート: 1. GET /health — パブリック。status "ok" と timestamp を返す 2. GET /api/profile — 保護。JWTクレームから sub と walletAddress を返す 3. GET /api/items — 保護。アイテムのプレースホルダー配列を返す 認証ミドルウェア(保護ルートに適用): - "Authorization: Bearer <token>" ヘッダーからトークンを取り出す - JWKSエンドポイントで署名を検証(jose の createRemoteJWKSet でキャッシュ) - iss、aud、exp クレームを検証 - デコードしたペイロードを req.user に付ける - 失敗時は 401 JSON でエラー "Unauthorized" を返す .env.example と全ルートの curl 実行例も含めること。
クライアントシークレット不要のパブリッククライアント向けフロントエンド実装。
バックエンドなしで OAuth2 PKCE フローで認証する React SPA を作成してください。 技術スタック: TypeScript、React 18、Vite、OAuthライブラリなし(PKCEを手動実装) OAuth2 設定: - 認可エンドポイント: https://auth.bravefrontierheroes.com/oauth2/auth - トークンエンドポイント: https://auth.bravefrontierheroes.com/oauth2/token - Client ID: YOUR_CLIENT_ID(パブリッククライアント — クライアントシークレットなし) - リダイレクトURI: http://localhost:5173/callback - スコープ: openid profile email offline_access PKCE実装: 1. 暗号論的に安全なランダム code_verifier を生成(43〜128文字、URLセーフ) 2. code_challenge = BASE64URL(SHA-256(ASCII(code_verifier))) を導出 3. リダイレクト前に sessionStorage に verifier を保存 4. 認証URLに code_challenge と code_challenge_method=S256 を含める 5. /callback でURLからcodeを取得、sessionStorageからverifierを取得してトークンエンドポイントにPOST トークン保存: メモリのみ(Reactのstate/context)。localStorage は使わないこと。 サイレントリフレッシュ: 有効期限の60秒前にリフレッシュトークンで更新する setTimeout をセット ページ: - / — 未認証なら「サインイン」ボタン、認証済みなら wallet_address とサインアウトを表示 - /callback — コード交換を処理して / にナビゲート ログイン後は id_token(JWT)をデコードして sub と wallet_address クレームを読み取る。