DrupalのSimple OAuthとPostmanを使ったOAuth認証の確認
概要
DrupalのSimple OAuthとPostmanを使ったOAuth認証の確認を行います。
以前に以下の記事を書きましたが、もう少し掘り下げてみます。
DrupalでSimple OAuthの設定を行う
以下を参考にしてください。
Postman
password
の場合
グラントタイプが/oauth/token に対して、Body > x-www-form-urlencoded に以下を指定しました。
キー | 値 |
---|---|
grant_type | password |
client_id | {作成したCLIENT_ID。例:gt8UKlKltI4qs1XP5KLucIXiYw9ulGb0xS4RyO437dc} |
client_secret | {作成したCLIENT_SECRET。例:test} |
username | {ユーザ名。例:yamato} |
password | {パスワード。例:yamato} |
結果、以下のようなJSONが返却されました。
{
"token_type": "Bearer",
"expires_in": 300,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJS...",
"refresh_token": "def50200295e412f..."
}
jwt.io
で確認したところ、以下のようにデコードされました。
{
"aud": "gt8UKlK...",
"jti": "6dc1fee..",
"iat": 1709386974,
"nbf": 1709386974,
"exp": 1709387274.122002,
"sub": "2",
"scope": [
"authenticated",
"cj"
]
}
sub
はDrupalのユーザのIDに該当し、scope
はDrupalで設定した値が返却されました。
異なるユーザでログインした場合、異なるsub
が与えられました。
ユーザ名またはパスワードをまちがえる
以下が返却されました。
{
"error": "invalid_grant",
"error_description": "The user credentials were incorrect.",
"message": "The user credentials were incorrect."
}
間違ったscopeを指定する
以下のように、間違ったscopeを指定します。
キー | 値 |
---|---|
grant_type | password |
client_id | {作成したCLIENT_ID。例:gt8UKlKltI4qs1XP5KLucIXiYw9ulGb0xS4RyO437dc} |
client_secret | {作成したCLIENT_SECRET。例:test} |
username | {ユーザ名。例:yamato} |
password | {パスワード。例:yamato} |
scope | test |
以下が返却されました。
{
"error": "invalid_scope",
"error_description": "The requested scope is invalid, unknown, or malformed",
"hint": "Check the `test` scope",
"message": "The requested scope is invalid, unknown, or malformed"
}
refresh_token
を使用する
グラントタイプグラントタイプrefresh_token
を使用する場合、username
とpassword
は不要で、refresh_token
を指定する必要がありました。
キー | 値 |
---|---|
grant_type | refresh_token |
client_id | {作成したCLIENT_ID。例:gt8UKlKltI4qs1XP5KLucIXiYw9ulGb0xS4RyO437dc} |
client_secret | {作成したCLIENT_SECRET。例:test} |
refresh_token | def50200a7d875010a068813927613be306944301b05358dd2dff39758cba3faa94ab2e6603c6a2e5a58d0262967f19fc6936ea764057f018df087c42fb5bcc0166db225efa7ce351dd6c82b64765350d6297e80e1118e9da7e004d2e17294d2b213b9d9c08ff16b29e6a59ffade5584e9aba4d2bda91b57cb7538c62b79520f... |
結果、以下のようなJSONが返却されました。
{
"token_type": "Bearer",
"expires_in": 300,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJS...",
"refresh_token": "def50200295e412f..."
}
client_credentials
を使用する
グラントタイプ以下のように、グラントタイプにclient_credentials
を指定してみました。
キー | 値 |
---|---|
grant_type | client_credentials |
client_id | {作成したCLIENT_ID。例:gt8UKlKltI4qs1XP5KLucIXiYw9ulGb0xS4RyO437dc} |
client_secret | {作成したCLIENT_SECRET。例:test} |
username | {ユーザ名。例:yamato} |
password | {パスワード。例:yamato} |
結果、以下のように、access_tokenのみを含むjsonが返却されました。
{
"token_type": "Bearer",
"expires_in": 300,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjIxZjYxOThlMWIxNTI0ZGM1NTcxZjJiZDM3N2M4NWI2N2IzYTE1NDU5MWVjZTUwN2QzNDEwNjBkYmVhNDEyOTg5MjI5NDAzYjFkOTFlODBmIn0.eyJhdWQiOiJndDhVS2xLbHR..."
}
グラントタイプpassword
と比較して、refresh_token
が含まれていませんでした。
ChatGPT 4に聞く
grant_type
の種類
grant_type
に指定する具体的な文字列は、OAuth 2.0仕様で定義されている値を使用します。以下は、主なgrant_type
の値とその用途です:
-
Authorization Code Grant
- 文字列:
authorization_code
- 用途: サーバーサイドWebアプリケーションで使用され、クライアントがリダイレクトを通じてユーザーのブラウザから認可コードを受け取り、そのコードを使ってアクセストークンを取得します。
- 文字列:
-
Implicit Grant
- 文字列:
implicit
- 用途: ブラウザベースのアプリケーション(例:シングルページアプリケーション)で使用されますが、セキュリティ上の理由からOAuth 2.0では推奨されず、OAuth 2.1では削除される予定です。
- 文字列:
-
Resource Owner Password Credentials Grant
- 文字列:
password
- 用途: ユーザーが信頼できるアプリケーションに直接ユーザーネームとパスワードを提供する場合に使用しますが、セキュリティ上の理由から推奨されません。
- 文字列:
-
Client Credentials Grant
- 文字列:
client_credentials
- 用途: アプリケーション自身の認証に使用され、主にアプリケーション間のAPIアクセスで利用されます。
- 文字列:
-
Refresh Token Grant
- 文字列:
refresh_token
- 用途: 既に取得したアクセストークンが失効した場合に、新しいアクセストークンを取得するために使用します。
- 文字列:
これらの値は、OAuthトークンエンドポイントへのリクエストでgrant_type
パラメータとして指定されます。適切なgrant_type
を選択することで、アプリケーションはOAuthサーバーと安全に通信し、必要な認証フローを実施できます。
passwordグラントタイプとclient_credentialsグラントタイプの違い
password
グラントタイプとclient_credentials
グラントタイプは、OAuth 2.0で定義されている異なる認証フローを表しており、それぞれ異なるユースケースとセキュリティ要件に対応しています。ここでは、それぞれの違いについて説明します。
Password Grant
-
グラントタイプ:
password
- 用途: このフローは、ユーザーがクライアントアプリケーションに直接自分のユーザー名とパスワードを提供できる信頼できるアプリケーションで使用されます。ユーザーがアプリケーションを信頼している場合に限り、この方法でユーザーの認証情報をアプリケーションに渡すことができます。
- セキュリティ: ユーザー名とパスワードを直接アプリケーションに渡すため、セキュリティリスクが高いとされ、一般的には推奨されません。特に、ユーザー認証情報の扱いには細心の注意が必要です。
Client Credentials Grant
-
グラントタイプ:
client_credentials
- 用途: このフローは、アプリケーション自身が認証される場合に使用されます。つまり、ユーザーの代わりにアクセスするのではなく、アプリケーションが自身の資格情報(クライアントIDとクライアントシークレット)を使用して認証を行い、APIやリソースへのアクセスを得るために使用します。
-
セキュリティ: このフローは、アプリケーション間の認証に限定され、ユーザー認証情報を扱わないため、
password
グラントタイプに比べてセキュリティリスクが低いとされます。アプリケーションは自身の資格情報を保持し、それを用いて認証を行います。
主な違い
-
認証対象:
password
はユーザーの認証情報を使用し、client_credentials
はアプリケーションの認証情報を使用します。 -
使用場面:
password
は特定の信頼できるクライアントアプリケーションに限定され、client_credentials
はアプリケーション間の認証に適しています。 -
セキュリティ:
password
はユーザー認証情報を直接扱うため、セキュリティ上の懸念がありますが、client_credentials
はアプリケーション自身の認証に限られるため、リスクが低いです。
適切なグラントタイプの選択は、アプリケーションのユースケース、セキュリティ要件、そしてユーザーとの信頼関係に基づいて行うべきです。
Nuxt 3で作成されたフロントエンドアプリケーションと、Drupalで構築されたバックエンド兼OAuthクライアントを例にすると?
Nuxt 3で作成されたフロントエンドアプリケーションと、Drupalで構築されたバックエンド兼OAuthクライアントを例にとって、password
グラントタイプとclient_credentials
グラントタイプを使った認証フローを説明します。
1. Password Grantフロー
このシナリオでは、ユーザーは直接Nuxt 3フロントエンドアプリケーションに認証情報(ユーザー名とパスワード)を提供します。その後、フロントエンドアプリケーションはこの情報を使用してDrupalバックエンドからトークンを取得します。
- ユーザー認証: ユーザーがNuxt 3アプリケーションにログイン情報(ユーザー名とパスワード)を入力します。
-
トークンリクエスト: Nuxt 3アプリケーションは、ユーザーから受け取った認証情報を
grant_type=password
と共にDrupalバックエンドのOAuthエンドポイントにPOSTリクエストとして送信します。 - トークンの発行: Drupalバックエンドはユーザーの認証情報を検証し、認証が成功するとアクセストークン(およびオプションでリフレッシュトークン)をNuxt 3アプリケーションに返します。
- アクセストークンの使用: Nuxt 3アプリケーションはこのアクセストークンを使用して、ユーザーの代わりにDrupalバックエンドの保護されたリソースへアクセスします。
2. Client Credentials Grantフロー
このシナリオでは、Nuxt 3アプリケーション自体がDrupalバックエンドに対して認証され、ユーザーではなくアプリケーション自身のためにリソースへのアクセスを要求します。
-
アプリケーション認証: Nuxt 3アプリケーションは、自身のクライアントIDとクライアントシークレットを使用してDrupalバックエンドのOAuthエンドポイントに
grant_type=client_credentials
と共にPOSTリクエストを送信します。 - トークンの発行: Drupalバックエンドはアプリケーションの認証情報を検証し、認証が成功するとアクセストークンをNuxt 3アプリケーションに返します。
- アクセストークンの使用: Nuxt 3アプリケーションはこのアクセストークンを使用して、アプリケーション自身のためにDrupalバックエンドの保護されたリソースへアクセスします。
選択基準
- Password Grantは、ユーザーがフロントエンドアプリケーションに直接ログインする必要がある場合に適しています。しかし、ユーザーの認証情報を直接扱うため、セキュリティに注意が必要です。
- Client Credentials Grantは、アプリケーションが自身のためにAPIを利用するシナリオ、例えばバックグラウンドでデータを同期する場合などに適しています。ユーザーの介在しない認証フローであり、アプリケーシ..
リフレッシュトークンの扱い
Nuxt3で作成したフロントエンドとDrupalで構築されたバックエンドを持つアプリケーションで、password
グラントタイプとclient_credentials
グラントタイプを使用したOAuth認証のフローについて説明します。このコンテキストでは、DrupalがOAuthクライアントの役割を果たし、フロントエンド(Nuxt3アプリ)からのリクエストを受けて、バックエンドである自身または別のサービスに対して認証を行います。
password
グラントタイプの場合
- ユーザー認証: Nuxt3アプリのユーザーがログインフォームにユーザー名とパスワードを入力します。
-
トークンリクエスト: Drupalバックエンドは、ユーザーから受け取った認証情報と
password
グラントタイプを使用して、OAuthサーバーにトークンをリクエストします。 - トークン応答: OAuthサーバーは、リクエストを検証し、認証情報が正しい場合はアクセストークンとリフレッシュトークンをDrupalに返します。
- アクセス&リフレッシュ: Drupalバックエンドはアクセストークンを使用して保護されたリソースへアクセスし、リフレッシュトークンを使用してアクセストークンが期限切れになった場合に新しいトークンを取得します。
client_credentials
グラントタイプの場合
-
アプリケーション認証: Drupalバックエンドが自身のクライアントIDとクライアントシークレットを使用して、OAuthサーバーに対して
client_credentials
グラントタイプでトークンリクエストを行います。 - トークン応答: OAuthサーバーはリクエストを検証し、クレデンシャルが正しい場合はアクセストークンのみをDrupalに返します。このケースではリフレッシュトークンは返されません。
- アプリケーション間のアクセス: Drupalバックエンドは取得したアクセストークンを使用して、他の保護されたリソースやAPIへのアクセスを行います。
リフレッシュトークンの扱い
-
password
グラントタイプ: ユーザー認証に基づき、アクセストークンとともにリフレッシュトークンも発行されます。リフレッシュトークンはアクセストークンが失効した場合に新しいアクセストークンを取得するために使用されます。 -
client_credentials
グラントタイプ: アプリケーション自身の認証に基づくため、リフレッシュトークンは通常発行されません。アクセストークンが失効した場合、アプリケーションは再度クライアントクレデンシャルを使用して新しいアクセストークンをリクエストする必要があります。
この違いは、password
グラントタイプがエンドユーザーの認証情報を扱うため、ユーザーのセッション管理にリフレッシュトークンが有用であるのに対し、client_credentials
グラントタイプはアプリケーション自体の認証であり、セッション管理が不要なシナリオで使用されるためです。
まとめ
OAuthで使用するグラントタイプの違いや、それに伴うrefresh_tokenの取り扱いの違いなどが少しずつわかってきました。
色々と誤っている点もあるかもしれませんが、参考になりましたら幸いです。
Discussion