Open Cloudは、クライアントが機密か公開かに基づいて、PKCE を用いたOAuth 2.0認可フローをサポートしています。
- _機密クライアント_は、秘密情報を安全に保管できるアプリであり、例えば、安全に秘密を保存および取得できるバックエンドを持つウェブサイトです。
- _公開クライアント_は、秘密を保持できないアプリであり、モバイルアプリやウェブブラウザアプリなどです。
私たちは、全てのクライアントに対してPKCEを用いたOAuth 2.0 認可コードフローを推奨し、公開クライアントにはそれを求めます。
認可コードフローを実装するには、アプリは以下のステップを実行します:
- コードバリファイアとコードチャレンジを生成します(PKCE のみ)。これにより、クライアントシークレットの代わりにリクエストにチャレンジを含めることができ、セキュリティが向上します。
- 適切なパラメーターを使用して、認可エンドポイントにGETリクエストを送信します。
- 認可コールバックを処理します。認可を得た後、アプリ作成時に指定したURLにリダイレクトリクエストを送信し、Robloxからの認可コードを使用します。後で使用するために認可コードを解析します。
- 認可コードを使用して、トークンエンドポイントにPOSTリクエストを送信します。成功すれば、API呼び出しに使用するアクセスおよびリフレッシュトークンを受け取ります。
- アクセスしたいリソースの参照ドキュメントに基づいて、OAuth 2.0 認証をサポートする任意のOpen Cloud APIを呼び出します。
以下のセクションでは、各ステップを詳しく説明します。
コードチャレンジを生成する(PKCEのみ)
認可プロセスを開始する前に、コードバリファイアからコードチャレンジを生成する必要があります。お好きなプログラミング言語のライブラリや組み込み関数を使用して、コードバリファイアを作成し、ハッシュを計算し、Base64エンコーディングを行ってコードチャレンジを生成できます。
コードバリファイアを作成する際は、予約されていない文字(大文字および小文字のアルファベット(A-Z, a-z)、10進数字(0-9)、ハイフン(-)、ピリオド(.)、アンダースコア(_)、チルダ(~))のみを使用し、最小長43文字、最大長128文字にしてください。
以下の例は、Javascriptを使用してコードバリファイアを作成し、SHA-256ハッシュアルゴリズムを使用してコードチャレンジを生成する方法を示しています:
コードチャレンジを生成する
const crypto = require('crypto');
// verifierとchallengeをbase64URLエンコード
function base64URLEncode(str) {
return str.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
// コードバリファイアからsha256ハッシュを作成
function sha256(buffer) {
return crypto.createHash('sha256').update(buffer).digest(`base64`);
}
// ランダムなコードバリファイアを作成
var code_verifier = base64URLEncode(crypto.randomBytes(32));
// コードバリファイアからチャレンジを生成
var code_challenge = base64URLEncode(sha256(code_verifier));
PKCEには、後のステップで両方の値(コードバリファイアとチャレンジ)が必要です。
認可URLを構築する
ユーザー認可プロセスを開始するには、必要なパラメーターを使用して認可URLを構築します:
- client_id: アプリ登録後に取得したアプリのクライアントID。
- redirect_uri: アプリのリダイレクトURI、アプリの再入ポイントです。
- scope: アプリが必要とするアクセス権限を定義する空白区切りのスコープリスト。
- response_type: 認可コードフローを示すためにcodeに設定します。
PKCE のみ必須
- code_challenge: コードバリファイアから生成されたコードチャレンジ。
- code_challenge_method: このパラメーターの値をS256に設定して、コードチャレンジがSHA-256アルゴリズムを使用して変換されたことを示します。これは、最も広くサポートされている安全なコードチャレンジメソッドです。
- state: リクエストとコールバック間で状態を維持するための不透明でセキュアなランダム値。
非PKCE のみ必須
- client_secret: アプリ登録後に取得したアプリのクライアントシークレット。PKCEを使用する場合は、このパラメーターを省略します。 認可リクエストのURLは、以下の例のように正しくフォーマットされている必要があります:
PKCE 認可URLの例https://apis.roblox.com/oauth/v1/authorize?client_id=7290610391231237934964&code_challenge=PLEKKVCjdD1V_07wOKlAm7P02NC-LZ_1hQfdu5XSXEI&code_challenge_method=S256&redirect_uri=https://example.com/redirect&scope=openid%20profile&response_type=code&state=abc123
ユーザーがこのURLにアクセスすると、彼らは認可フローを進んでいきます。成功すると、Robloxはユーザーを指定したredirect_uriにリダイレクトします。
認可コールバックを処理する
認可フローが成功した場合、アプリには指定したredirect_uriにRoblox認可サーバーからのGETリクエストが届きます。そのリクエストには、code(認可コード) および state(以前に提供した場合)パラメーターが含まれます。
codeパラメーターには、アプリが認可サーバーからアクセストークンに交換できる認可コードが含まれています。ほとんどのバックエンドサーバー言語には、クエリパラメーターにアクセスする標準的な方法があります。codeパラメーターを取得し、それを使用してアクセストークンに交換する必要があります。
stateパラメーターは、最初の認可リクエストで提供した不透明な値です。このパラメーターを使用して、認可プロセスの状態またはコンテキストを維持できます。
例えば、リダイレクトURIをhttps://example.com/redirectに指定している場合、以下のようなURLでGETリクエストを受け取るかもしれません。
リダイレクトURLの例https://example.com/redirect?code=10c45PNuquKnFJ6pUcy5-fHkghEM6lSegm-7hj9mVEprub1dSDuStuKK_EAUXY7AHTD63xcnmvxSLthp-C8g3jzIGZVzuXSd20Y2dEYI9hx0LZmPg95ME4z2K03UheiZbroyXUjYyB3ReoMqobzDVPzyx6IS8kj2Uu-11Xq_0JiTYxtDatuqXRNIAmJT8gMJmbSyOLOP_vnDvbeMUiBsqCRrkTGVbWSwYSc8sTVVE-535kYdqQOgNjH1ffCoZLGl8YYxLnpb2CXJlRQPrcjkA&state=6789
認可が失敗した場合、アプリには、指定されたリダイレクトURLに対してerror、error_description、およびstate(該当する場合)パラメーターを含むGETリクエストが届きます。
- errorパラメーターは、認可プロセス中に発生した特定のOAuth 2.0エラーを示します。
- error_descriptionパラメーターは、エラーの追加詳細を提供します。
- stateパラメーターは、失敗の場合の状態を維持するためにアプリが使用します。
認可コードをアクセストークンに交換する
認可codeを解析したら、それを使用して希望するRobloxリソースへのアクセスを得るためのトークンに交換します:
トークン交換エンドポイントにPOSTリクエストを送信して、アクセストークンとリフレッシュトークンを要求します。リクエストには、認可コード、クライアントID、およびコードバリファイア値(PKCE)またはクライアントシークレット(非PKCE)をx-www-form-urlencoded形式で含める必要があります。
受信したレスポンスから適用可能なトークンを解析します。アクセストークンは15分間有効です。リフレッシュトークンは安全に保管し、通常はサーバー側に保管して、将来的に新しいトークンを取得するために使用します。
トークンエンドポイントレスポンスの例{"access_token": "eyJhbGciOiJFUzI1NiIsImtpZCI6IlBOeHhpb2JFNE8zbGhQUUlUZG9QQ3FCTE81amh3aXZFS1pHOWhfTGJNOWMiLCJ0eXAiOiJKV11234.eyJzdWIiOiIyMDY3MjQzOTU5IiwiYWlkIjoiM2Q2MWU3NDctM2ExNS00NTE4LWJiNDEtMWU3M2VhNDUyZWIwIiwic2NvcGUiOiJvcGVuaWQ6cmVhZCBwcm9maWxlOnJlYWQiLCJqdGkiOiJBVC5QbmFWVHpJU3k2YkI5TG5QYnZpTCIsIm5iZiI6MTY5MTYzOTY5OCwiZXhwIjoxNjkxNjQwNTk4LCJpYXQiOjE2OTE2Mzk2OTgsImlzcyI6Imh0dHBzOi8vYXBpcy5yb2Jsb3guY29tL29hdXRoLyIsImF1ZCI6IjcyOTA2MTAzOTc5ODc5MzQ5Nj1234.BjwMkC8Q5a_iP1Q5Th8FrS7ntioAollv_zW9mprF1ats9CD2axCvupZydVzYphzQ8TawunnYXp0Xe8k0t8ithg","refresh_token": "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwia2lkIjoidGpHd1BHaURDWkprZEZkREg1dFZ5emVzRWQyQ0o1NDgtUi1Ya1J1TTBBRSIsInR5cCI6IkpXVCJ9..nKYZvjvXH6msDG8Udluuuw.PwP-_HJIjrgYdY-gMR0Q3cabNwIbmItcMEQHx5r7qStVVa5l4CbrKwJvjY-w9xZ9VFb6P70WmXndNifnio5BPZmivW5QkJgv5_sxLoCwsqB1bmEkz2nFF4ANLzQLCQMvQwgXHPMfCK-lclpVEwnHk4kemrCFOvfuH4qJ1V0Q0j0WjsSU026M67zMaFrrhSKwQh-SzhmXejhKJOjhNfY9hAmeS-LsLLdszAq_JyN7fIvZl1fWDnER_CeDAbQDj5K5ECNOHAQ3RemQ2dADVlc07VEt2KpSqUlHlq3rcaIcNRHCue4GfbCc1lZwQsALbM1aSIzF68klXs1Cj_ZmXxOSOyHxwmbQCHwY7aa16f3VEJzCYa6m0m5U_oHy84iQzsC-_JvBaeFCachrLWmFY818S-nH5fCIORdYgc4s7Fj5HdULnnVwiKeQLKSaYsfneHtqwOc_ux2QYv6Cv6Xn04tkB2TEsuZ7dFwPI-Hw2O30vCzLTcZ-Fl08ER0J0hhq4ep7B641IOnPpMZ1m0gpJJRPbHX_ooqHol9zHZ0gcLKMdYy1wUgsmn_nK_THK3m0RmENXNtepyLw_tSd5vqqIWZ5NFglKSqVnbomEkxneEJRgoFhBGMZiR-3FXMaVryUjq-N.Q_t4NGxTUSMsLVEppkTu0Q6rwt2rKJfFGuvy3s12345","token_type": "Bearer","expires_in": 899,"id_token": "eyJhbGciOiJFUzI1NiIsImtpZCI6IkNWWDU1Mi1zeWh4Y1VGdW5vNktScmtReFB1eW15YTRQVllodWdsd3hnNzgiLCJ0eXAiOiJKV11234.eyJzdWIiOiIyMDY3MjQzOTU5IiwibmFtZSI6ImxpbmtzZ29hdCIsIm5pY2tuYW1lIjoibGlua3Nnb2F0IiwicHJlZmVycmVkX3VzZXJuYW1lIjoibGlua3Nnb2F0IiwiY3JlYXRlZF9hdCI6MTYwNzM1NDIzMiwicHJvZmlsZSI6Imh0dHBzOi8vd3d3LnJvYmxveC5jb20vdXNlcnMvMjA2NzI0Mzk1OS9wcm9maWxlIiwibm9uY2UiOiIxMjM0NSIsImp0aSI6IklELnltd3ZjTUdpOVg4azkyNm9qd1I5IiwibmJmIjoxNjkxNjM5Njk4LCJleHAiOjE2OTE2NzU2OTgsImlhdCI6MTY5MTYzOTY5OCwiaXNzIjoiaHR0cHM6Ly9hcGlzLnJvYmxveC5jb20vb2F1dGgvIiwiYXVkIjoiNzI5MDYxMDM5Nzk4NzkzNDk2NCJ9.kZgCMJQGsariwCi8HqsUadUBMM8ZOmf_IPDoWyQY9gVX4Kx3PubDz-Q6MvZ9eU5spNFz0-PEH-G2WSvq2ljDyg","scope": "openid profile"}
リソースメソッドへの呼び出しを行う
必要なアクセストークンを取得したので、それを使用してリソースメソッドへの認証済み呼び出しを行うことができます。全てのAPIリクエストのヘッダーにアクセストークンを含めて、それらを認可します。
例えば、アプリが正しく機能するかどうかをテストするために、全ての認可フローを経て、アクセストークンを使用してuser情報エンドポイント にGETリクエストを送信できます。このエンドポイントを呼び出す前に、openidまたは両方のopenidとprofileスコープを持っていることを確認してください。成功すると、そのエンドポイントからのレスポンスは次のようになります:
ユーザー情報レスポンスの例
{
"sub": "12345678",
"name": "Jane Doe",
"nickname": "robloxjanedoe",
"preferred_username": "robloxjanedoe",
"created_at": 1607354232,
"profile": "https://www.roblox.com/users/12345678/profile"
}