JWT の構築:クライアントサイドのリクエストに対するアクセスポリシーの管理
JS SDKを使用するには、クライアント側がアクセス可能なリソースの認証手段として、サーバーコードからJWTを生成することが必要です。 そしてサーバー側では、JWTの署名が指定された AccountSid
の AuthToken
で署名されているかどうか確認することでリクエストを認証します。
これにより、クライアントサイドで AuthToken を公開することなく、アプリケーションの API リクエストを認証および承認し、全員が参照できるメカニズムが可能になります。
JWT フォーマット
JWT は 3 つのハッシュ化されたセクションから構成されます。
- ヘッダー
- ペイロード
- 署名
まず、JWT の小さい 2 つのセクションを見てみましょう。
ヘッダー
JWT トークンの最初の部分はヘッダーで、さらに 2 つの部分から構成されます。
{ "typ": "JWT", "alg": "HS256" }
これは、これが本当に JWT であり、使用しているハッシュアルゴリズムが HS256 であることを示します。
署名
JSON ウェブトークンの 3 つ目最後の部分は、署名です。この署名は、以下のコンポーネントのハッシュから構成されます。
- ヘッダー
- ペイロード
- Secret
式を使うと、以下のようになります。
hash((hash(header) + hash(payload)), 'secret')
secret は各自の AuthToken です。
ペイロード
JWT のペイロードによって、リソースに対するアクセスポリシーが定義されます。
アクセスポリシーオブジェクト
アクセスポリシーオブジェクトは、HTTP REST リクエストに適用可能なルールセットであり、このリクエストに API リソースへのアクセスを許可するかどうかを決定します。ポリシーによって、アクセスが許可されるリソースおよびサブリソース、必要なパラメーターや使用可能なパラメーター、リソースとサブリソースを完全に拒否するのかどうかが定義されます。 アクセスポリシーは、JSON オブジェクトとして表されます。
アクセスポリシーオブジェクトは、以下のフィールドを持つ JSON オブジェクトです。
Key | 概要 |
---|---|
account_sid | このアクセスポリシーが代表して適用されるアカウント SID。 |
version | 使用しているアクセスポリシーのドキュメントフォーマットのバージョン。 |
friendly_name | オプションの人間が読みやすい形式の説明文字列。 |
ポリシー | ポリシールールオブジェクトの配列(「ポリシールールオブジェクト」を参照)。 |
ポリシールールオブジェクト
「ポリシー」配列には、ポリシールールオブジェクトが格納されます。
Key | 概要 |
---|---|
url | The URL pattern of the rule. |
method | このルールがマッチングする HTTP メソッド。 |
allow | true または false。このルールがアクセスを許可するかどうか。 デフォルトは false です。 |
post_filter | このルールにマッチングするために必要な www-form-encoded パラメーターおよび値を記述するオブジェクト。未定義の場合は、すべてのパラメーターおよび値がマッチングします。 |
query_filter | このルールにマッチングするために必要な URL クエリーパラメーターおよび値を記述するオブジェクト。未定義の場合は、すべてのパラメーターおよび値がマッチングします。 |
url
「url」キーは、リクエストの URL とマッチングされるリテラルまたはパターンを定義します。
このフィールドには、クエリーパラメーターを伴わない URL が入り、リテラル文字列を使用するか、または末尾にワイルドカード文字列を指定します。このルールにマッチングするには、リテラル文字列がリクエストの URL と完全に一致しなければなりません。ワイルドカード文字列は、以下の 2 種類あります。
- 直接の子のワイルドカード(末尾に「/*」が付く URL)。
- 再帰的なワイルドカード(末尾に「/**」が付く URL)。
直接の子のワイルドカードを使ったルールでは、パスの次のステップにマッチングしますが、それ以降はマッチングしません。
たとえば、次のようになります。
- https://taskrouter.twilio.com/v1/Workspaces/*
マッチング:
- https://taskrouter.twilio.com/v1/Workspaces/WSxxx
ただし、以下の URL にはマッチングしません。
- https://taskrouter.twilio.com/v1/Workspaces/
- https://taskrouter.twilio.com/v1/Workspaces/WSxxx/TaskQueues
再帰的なワイルドカードでは、このパスの任意の子 URL とマッチングします。
たとえば、次のようになります。
- https://taskrouter.twilio.com/v1/Workspaces/WSxxx/**
マッチング:
- https://taskrouter.twilio.com/v1/Workspaces/WSxxx/TaskQueues
- https://taskrouter.twilio.com/v1/Workspaces/WSxxx/TaskQueues/WQxxx
- https://taskrouter.twilio.com/v1/Workspaces/WSxxx/Workers/WKxxx/Statistics
- https://taskrouter.twilio.com/v1/Workspaces/WSxxx/Statistics
ただし、以下の場合はマッチングしません。
- https://taskrouter.twilio.com/v1/Workspaces/WSxxxx
- https://taskrouter.twilio.com/v1/Workspaces
複数ルールのマッチング
- リクエストが複数のルールにマッチングする場合、最も具体的なルールが優先されます。
- 長い具体的なパスが優先されます。
- パスが同じ場合は、フィルターがあるルールが優先されます。
- 直接競合するルールは無効とみなされ、アクセスポリシーパーサーで検出され、却下されます。
method
このルールが適用される HTTP メソッド:GET、POST、DELETE
allow
allow には、true または false の値を指定できます。マッチングルールで allow の値が「true」であると、リクエストは承認されます。allow の値が false の場合、リクエストは明示的に拒否されます。すべてのルールのデフォルトは「false」です。
post_filter および query_filter
post_filter および query_filter フィールドは、クエリー文字列または www-form-post-params で指定されたパラメーターとのマッチングに使われます。値は、パラメーター名をキーとするオブジェクトで、マッチングする必要がある文字列リテラルか、またはキーがどのようにマッチングするか詳しく記述する Matcher オブジェクトです。post_filter と query_filter どちらも同じフォーマットを使います。
文字列リテラルの例
"post_filter": { "FriendlyName": "Alice" }
これは、単一の www-form-encoded パラメーターである FriendlyName の値が Alice であるリクエストとマッチングします。これ以外の形式のパラメーターがリクエストに含まれる場合は、このルールにマッチングしません。
Matcher オブジェクトの例
"post_filter": { "FriendlyName": {"required": true}, "Status": {"required": false}, "Foo": {"required": false, "value": "bar"} }
Matcher オブジェクトで、より複雑なマッチングルールが可能です。上記の例では、「FriendlyName」フィールドは必須ですが、どの値を指定してもマッチングします。「Status」フィールドはオプションであるため、指定しても指定しなくても、このルールにマッチングします。指定した場合は、任意の値を使用できます。「Foo」フィールドもオプションですが、指定する場合は値「bar」が必要です。
Matcher オブジェクト
Key | 概要 |
---|---|
必須 | このパラメーターは必須で、true または false です。 |
value optional. | 指定する場合、フィールドの値がマッチングしなければならない文字列リテラルです。指定しない場合は、任意の値とマッチングします。 |
標準的な JWT ペイロードフィールド
ポリシーのリストに加え、ペイロードで以下を定義する必要があります。
- iss:トークンの発行者(AccountSid)
- exp:トークンの有効期限が切れる日時(エポックからの秒数のタイムスタンプ)
- account_sid:トークンのアカウント所有者
- workspace_sid: トークンのWorkspace所有者
- チャンネル:アップデートを受け取り、API リクエストを POST する先のチャンネル。
Workerを定義している場合は、以下の定義も必要になります。
- チャンネル:WSxxx
- worker_sid:WKxxx
Workspaceを定義している場合は、以下の定義も必要になります。
- チャンネル:WSxxx
必須ポリシー
JWTの2つの必須ポリシーは、Web-socketチャネルに接続し、そのWeb-socketでメッセージをPOSTしてREST APIを実行できるようにすることです。 これらは、最初にWeb-socketを開いた場合の認証および承認を行うために必要です。 他のAPIに対するGET、POST、またはDELETEの以降のEventでは、このウェブソケットが使われます。
たとえば、次のようになります。
{ "url": "https://event-bridge.twilio.com/v1/wschannels/AccountSid/Channel", "method": "GET", "allow": true }, { "url": "https://event-bridge.twilio.com/v1/wschannels/AccountSid/Channel", "method": "POST", "allow": true }
ヘルパーライブラリーメソッドをポリシーオブジェクトに分解する
ヘルパーライブラリーを使った例を挙げ、ポリシーオブジェクトとしてどのように分解されるか見てみましょう。
<?php $workspaceCapability = new Services_Twilio_TaskRouter_Capability($accountSid, $authToken, $workspaceSid, $workspaceSid); $workspaceCapability->allowFetchSubresources(); $workspaceCapability->allowDeleteSubresources(); $workspaceCapability->allowUpdatesSubresources(); $workspaceToken = $workspaceCapability->generateToken();
ポリシーオブジェクトは以下のようになります。
{ "url": "https://event-bridge.twilio.com/v1/wschannels/ACxxx/WSxxx", "method": "GET", "allow": true }, { "url": "https://event-bridge.twilio.com/v1/wschannels/ACxxx/WSxxx", "method": "POST", "allow": true }, { "url": "https://taskrouter.twilio.com/v1/Workspaces/WSxxx", "method": "GET", "allow": true }, { "url": "https://taskrouter.twilio.com/v1/Workspaces/WSxxx/**", "method": "GET", "allow": true }, { "url": "https://taskrouter.twilio.com/v1/Workspaces/WSxxx/**", "method": "POST", "allow": true }, { "url": "https://taskrouter.twilio.com/v1/Workspaces/WSxxx/**", "method": "DELETE", "allow": true }
全体で、JWT ペイロードは以下のようにデコードされます。
{ "version": "v1", "friendly_name": "WSxxx", "policies": [ { "url": "https://event-bridge.twilio.com/v1/wschannels/ACxxx/WSxxx", "method": "GET", "allow": true }, { "url": "https://event-bridge.twilio.com/v1/wschannels/ACxxx/WSxxx", "method": "POST", "allow": true }, { "url": "https://taskrouter.twilio.com/v1/Workspaces/WSxxx", "method": "GET", "allow": true }, { "url": "https://taskrouter.twilio.com/v1/Workspaces/WSxxx/**", "method": "GET", "allow": true }, { "url": "https://taskrouter.twilio.com/v1/Workspaces/WSxxx/**", "method": "DELETE", "allow": true }, { "url": "https://taskrouter.twilio.com/v1/Workspaces/WSxxx/**", "method": "POST", "allow": true } ], "iss": "ACxxx", "exp": 1432251317, "account_sid": "ACxxx", "channel": "WSxxx", "workspace_sid": "WSxxx" }
ヘルプが必要ですか?
誰しもが一度は考える「コーディングって難しい」。そんな時は、お問い合わせフォームから質問してください。 または、Stack Overflow でTwilioタグのついた情報から欲しいものを探してみましょう。