OAuth 2.0について
仕様
認可フロー
RFC6749 で定義されている認可フロー(Authorization Grant)のうち、Authorization Code Grant にのみ対応しています。
機能
現在公開中のすべてのChatwork APIをご利用いただけます。
クライアントプログラムからChatwork APIを利用する方法
1.クライアントの登録
OAuthクライアント作成画面 よりクライアント登録をおこなってください。
クライアントの情報として、下記の項目を登録します。
項目 | 必須 | 説明 |
---|---|---|
クライアント名 | ◯ | クライアントの名前です。 |
クライアントタイプ | ◯ | クライアントの種別です。 |
項目 | 必須 | 説明 |
---|---|---|
クライアント名 | ◯ | クライアントの名前です。 |
クライアントタイプ |
クライアントの種別です。
コンフィデンシャルクライアント
パブリッククライアント |
|
リダイレクトURI | ◯ |
最低1つ、最大で5つまで登録できます。
コンフィデンシャルクライアント
パブリッククライアント |
スコープ | ◯ |
最低1つは登録が必要です。各Chatwork APIを叩くために必要なスコープは、Appendixスコープ一覧 を参照してください。 ただし、`offline_access` が利用できるのは、コンフィデンシャルクライアントのみです。 |
2.認可コード(Authorization Code)の取得
認可コードを取得するためには、Web ブラウザにてコンセント画面にアクセスする必要があります。
コンセント画面へのアクセス方法
必要なクエリパラメータを設定した上で コンセント画面 にアクセスすると、コンセント画面が表示されます。
※ ログイン画面が表示された場合は、認証情報を入力してからログインするとコンセント画面へリダイレクトされます。
クエリパラメータ
パラメータ名 | 指定する値 | 必須 | 説明 |
---|---|---|---|
response_type | 文字列 | ◯ | 現在は code にしか対応していません。 |
client_id | 文字列 | ◯ | クライアントIDを指定してください。 |
redirect_uri | 文字列 |
クライアント登録時に設定されたURLの中から指定してください。 例: 複数の |
|
scope | 文字列(スペース区切り) | ◯ |
rooms.all:read_write
|
state | 文字列 |
CSRF攻撃対策として使う文字列で、リソースオーナーのセッションに紐付けて管理します。リソースオーナーが認可許可または認可拒否をおこなったとき、ここでセットした 例: The OAuth 2.0 Authorization Framework 10.12. Cross-Site Request Forgery |
|
code_challenge | 文字列 | ※ |
コンフィデンシャルクライアント の場合は任意 値は、後にトークンエンドポイントで使用する、
算出結果の文字列長は43文字から128文字、文字種としては正規表現で |
code_challenge_method | 文字列 | ※ |
コンフィデンシャルクライアントの場合は任意
|
例: コンセント画面を表示するためのURL
https://www.chatwork.com/packages/oauth2/login.php?
response_type=code
&redirect_uri=https://example.com/callback.php
&client_id=Lvo0YN92ga5kP
&state=811435b3683ae95c1cf3197deaf1bfe4b411f587
&scope=rooms.all:read_write%20users.profile.me:read
&code_challenge=jlkGAsNvHshJNC7uXSSmC2tALONajPdupVf3TScb7zk
&code_challenge_method=S256
認可コードの発行
コンセント画面においてリソースオーナーが「許可」ボタンを押すと認可コードが発行され、redirect_uri
に認可コードをクエリパラメータとしてセットした上でリダイレクトされます。
例: 認可コード発行時のリダイレクト先
- code
- 認可コード、有効期限は1分間
- state
- コンセント画面を表示する際に指定していた
state
の値
https://example.com/callback.php?
code=a2f0c1fe96af8c3a46fa0
&state=811435b3683ae95c1cf3197deaf1bfe4b411f587
認可の拒否
コンセント画面において、リソースオーナーが「拒否」ボタンを押すと認可を拒否し、redirect_uri
にリダイレクトされます。
- error
access_denied
で固定- state
- コンセント画面を表示する際に指定していた
state
の値
https://example.com/callback.php?error=access_denied
ログイン画面における制約
OAuth2専用ログイン画面ではSAML認証には対応しておりません。通常のログイン画面を経由してSAML認証でログインした後、再度コンセント画面にアクセスしてください。
3.アクセストークンの発行/再発行
リクエスト
エンドポイント
HTTPのPOSTメソッドで下記のエンドポイントにアクセスしてください。
https://oauth.chatwork.com/token
認証
コンフィデンシャルクライアントの場合は、Basic認証にしたがい、ユーザー名には クライアント ID、パスワードには クライアントシークレット を指定し、それらをコロン :
で結合した文字列をBase64でエンコードしてください。これらの情報はクライアント管理画面から確認できます。
パブリッククライアントの場合は、Basic認証は不要で、クエリ文字列として client_id=クライアント ID
を含めてください。
例.
authorization: Basic THZvMFl1OO==
リクエストボディのフォーマット
application/x-www-form-urlencoded
ボディパラメータ
認可コードから発行する場合(初回)
パラメータ名 | 指定する値 | 必須 | 例 |
---|---|---|---|
grant_type | 文字列 | ◯ | authorization_code を指定してください。 |
code | 文字列 | ◯ | 認可許可ボタンを押して取得した認可コードを指定してください。 |
redirect_uri | 文字列 |
コンセント画面を表示する際に 例. https://example.com/callback |
|
code_verifier | 文字列 | ※ |
認可リクエストで、 文字列長は43文字から128文字、文字種としては正規表現で |
リフレッシュトークンを使って再発行する場合(2回目以降)
パラメータ名 | 指定する値 | 必須 | 例 |
---|---|---|---|
grant_type | 文字列 | ◯ | refresh_token を指定してください。 |
refresh_token | 文字列 | ◯ | トークン発行時に生成された refresh_token の値を指定してください。 |
scope | 文字列 | users.profile.me:read |
レスポンス
レスポンスボディのフォーマット
application/json
レスポンスボディ(トークン発行時、再発行時で共通)
正常時
JSONのフィールド名 | JSONの値の形式 | nullable | 例 | 説明 |
---|---|---|---|---|
access_token | String | 有効期間は30分間 | ||
refresh_token | String | 有効期間は14日間(offline_access スコープを含む場合は無期限) | ||
token_type | String | ◯ | Bearer | |
expires_in | Int | ◯ | access_token の有効期間(秒) | |
scope | String | ◯ |
エラー時
JSONのフィールド名 | JSONの値の形式 | nullable | 例 | 説明 |
---|---|---|---|---|
error | String | invalid_grant | エラーのときに返るフィールド | |
error_description | String | ◯ | エラーのときに返るフィールド | |
error_uri | String | ◯ | エラーのときに返るフィールド。常にnull |
例: curl
コマンドでトークンを発行する
curl
コマンドでトークンを発行するリクエスト
# コンフィデンシャルクライアントの場合
curl -v --user 'Lvo0YN92ga5kP:secret' \
-X POST -d 'grant_type=authorization_code \
&code=26d13798facc9a0ca05a8cb7246020f15a311 \
&redirect_uri=https://127.0.0.1/callback \
&code_verifier=5b0029bd34e559e0abe7a37051aa411398913fc3579e27bd963a2b9a647f12f58a335beeb4d83a53a74ff1a6f99f6af385d2992c73beead39f57dcee95e0f954' \
https://oauth.chatwork.com/token
# パブリッククライアントの場合
curl -v -X POST -d 'grant_type=authorization_code \
&client_id=Lvo0YN92ga5kP \
&code=26d13798facc9a0ca05a8cb7246020f15a311 \
&redirect_uri=https://127.0.0.1/callback
&code_verifier=5b0029bd34e559e0abe7a37051aa411398913fc3579e27bd963a2b9a647f12f58a335beeb4d83a53a74ff1a6f99f6af385d2992c73beead39f57dcee95e0f954' \
https://oauth.chatwork.com/token
レスポンス
> POST /token HTTP/2
> Host: 127.0.0.1
> authorization: Basic THZvMFlOOTJnYTVrUDphYmNkZWZnaGlqa2xubW9wcXJzdHV2d3h5ejAxMjM0NTY3ODk=
> accept: */*
> content-length: 199
> content-type: application/x-www-form-urlencoded
>
< HTTP/2 200
< cache-control: no-store
< pragma: no-cache
< content-type: application/json
< content-length: 989
{
"access_token": "eyJjdHkiOiJKV1QiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImlOUVh0dFR2RHZhcDVkSWpGQzA5ZHZadHFXaGQ2WmFRb2pKenVuUS1vV28ifQ.eyJhdWQiOiJodHRwczovL2FwaS5jaGF0d29yay5jb20iLCJzdWIiOiIzIiwiYWNjb3VudF9pZCI6IjMiLCJzY29wZSI6WyJhbGwiXSwiaXNzIjoiaHR0cHM6Ly9vYXV0aC5jaGF0d29yay5jb20iLCJleHAiOjE1MDExMzgwNDEsImlhdCI6MTUwMTEzNzE0MSwianRpIjoiOTcwNDAwOWItNTdlNi00NDU5LTg5NzMtNjc3ZmM5YjA5MjgyIiwiY2xpZW50X2lkIjoiTHZvMFlOOTJnYTVrUCJ9.BIS8QvyTHz7KK_fnmvc0fa8NQDOWy7v8Ni0LvLyuROE5UEi7l_HxDT8tHLTQLELIm3jOw4SiW94KPYwduRL467vJ2j2eNT-zTkCXtEN8pxbA0HtnBrtCcp0dRJEMnfBegzkoAe8BTB6gee3rrXy6sQcLb19WBrrHNbjICFL0--SG3IvPanOzABqiNMqfScnasTtj7xtIaNpbxf8LDIH3EF150Iif4BqSczJr-XppBTBYuP32UlBnRlQOXvXqymGijQXgqDOo3LLFY_k62OoPYAQ3UXkaum86Al-DJM6iC-043kBINbYLLPo0uwwsolmjRDG5zBzPC0GtcjXiLy4Gqg",
"token_type": "Bearer",
"expires_in": 1800,
"refresh_token": "86277ab4fd9d111bd3225215d96d622c9ae6810d82cd6d0e9530bf35adda67ab7d3c24e2a0052e9d3b442ce212ca17ecf07ddbd8c3477aa3abde15e4ebcf7b53",
"scope": "rooms.all:read_write"
}
4. Chatwork APIへのアクセス
リクエスト
Chatwork APIへリクエストを送る際に、従来の Chatwork APIの認証方法 ではなく、authorization
リクエストヘッダーにBearer認証スキームでアクセストークン(access_token
)をセットしてください。
例: authorization
ヘッダーの指定
authorization
ヘッダーの指定authorization: Bearer eyJjdHkiOiJKV1QiLCJ0eXAiOiJKV1QiLCJh
bGciOiJSUzI1NiIsImtpZCI6ImlOUVh0dFR2RHZhcDVkSWpGQzA5Z
HZadHFXaGQ2WmFRb2pKenVuUS1vV28ifQ.eyJhdWQiOiJodHRwcz
ovL2FwaS5jaGF0d29yay5jb20iLCJzdWIiOiIzIiwiYWNjb3VudF9pZC
I6IjMiLCJzY29wZSI6WyJhbGwiXSwiaXNzIjoiaHR0cHM6Ly9vYXV0a
C5jaGF0d29yay5jb20iLCJleHAiOjE1MDExMzgwNDEsImlhdCI6MTU
wMTEzNzE0MSwianRpIjoiOTcwNDAwOWItNTdlNi00NDU5LTg5NzMt
Njc3ZmM5YjA5MjgyIiwiY2xpZW50X2lkIjoiTHZvMFlOOTJnYTVrUCJ9.
BIS8QvyTHz7KK_fnmvc0fa8NQDOWy7v8Ni0LvLyuROE5UEi7l_Hx
DT8tHLTQLELIm3jOw4SiW94KPYwduRL467vJ2j2eNT-zTkCXtEN
8pxbA0HtnBrtCcp0dRJEMnfBegzkoAe8BTB6gee3rrXy6sQcLb19
WBrrHNbjICFL0--SG3IvPanOzABqiNMqfScnasTtj7xtIaNpbxf8LDIH3E
F150Iif4BqSczJr-XppBTBYuP32UlBnRlQOXvXqymGijQXgqDOo3LLFY
_k62OoPYAQ3UXkaum86Al-DJM6iC-043kBINbYLLPo0uwwsolmjRD
G5zBzPC0GtcjXiLy4Gqg
レスポンス
Chatwork APIの 各エンドポイント ドキュメントを参照してください。
エラー
アクセストークンが失効している場合や不正な場合には www-authenticate ヘッダーにエラー情報をセットされます。
例: アクセストークンが失効している場合
HTTP/2 401
www-authenticate: Bearer error="invalid_token", error_description="The access token expired"
例: curl
コマンドでChatwork APIにアクセスする
curl
コマンドでChatwork APIにアクセスするcurl -v -H 'authorization: Bearer eyJjdHkiOiJKV1QiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImlOUVh0dFR2RHZhcDVkSWpGQzA5ZHZadHFXaGQ2WmFRb2pKenVuUS1vV28ifQ.eyJhdWQiOiJodHRwczovL2FwaS5jaGF0d29yay5jb20iLCJzdWIiOiIxNzMiLCJhY2NvdW50X2lkIjoiMTczIiwic2NvcGUiOlsiYWxsIl0sImlzcyI6Imh0dHBzOi8vb2F1dGguY2hhdHdvcmsuY29tIiwiZXhwIjoxNTAyMjUxNDU4LCJpYXQiOjE1MDIyNDk2NTgsImp0aSI6IjRlNzg5ZTAzLTk2NjAtNDc4MC1hYThkLTVmZjk2YmU0MzMyNSIsImNsaWVudF9pZCI6Ikx2bzBZTjkyZ2E1a1AifQ.Y14Sr0SmtgwLegwWPMeQlPut2XmP74y3QdupCAN7Hc5Id10Qvgq-csuYVxxAYStqZUO4sZ_j9SeE7-rqhuNowDMwqVaTGfDvAvtQLitPKDUb2g6x87c-lfffkJkIiL1xcH3lHrmQkBa_H81-_a3VFJila8hFptvygOp19OSDSrUIlcq6PeHlfNQtXjs2VFREQydQNE2cdLe68Nh5F5V4HX20C449MKNWK4ybwmFrnX-o9KgERaP1rjrCcWYrZ-lK8TquHti9XMfSaj71eDkfPVOLyCOe1_zBEEH8NRFtN2OcVQWJFPy09rz1yw7a1YARdsU4DukrhWvWcVxIad8ygA' \
'https://api.chatwork.com/v2/me'
> GET /v2/me HTTP/2
> Host: api.chatwork.com
> accept: */*
> authorization: Bearer eyJjdHkiOiJKV1QiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImlOUVh0dFR2RHZhcDVkSWpGQzA5ZHZadHFXaGQ2WmFRb2pKenVuUS1vV28ifQ.eyJhdWQiOiJodHRwczovL2FwaS5jaGF0d29yay5jb20iLCJzdWIiOiIxNzMiLCJhY2NvdW50X2lkIjoiMTczIiwic2NvcGUiOlsiYWxsIl0sImlzcyI6Imh0dHBzOi8vb2F1dGguY2hhdHdvcmsuY29tIiwiZXhwIjoxNTAyMjUxNDU4LCJpYXQiOjE1MDIyNDk2NTgsImp0aSI6IjRlNzg5ZTAzLTk2NjAtNDc4MC1hYThkLTVmZjk2YmU0MzMyNSIsImNsaWVudF9pZCI6Ikx2bzBZTjkyZ2E1a1AifQ.Y14Sr0SmtgwLegwWPMeQlPut2XmP74y3QdupCAN7Hc5Id10Qvgq-csuYVxxAYStqZUO4sZ_j9SeE7-rqhuNowDMwqVaTGfDvAvtQLitPKDUb2g6x87c-lfffkJkIiL1xcH3lHrmQkBa_H81-_a3VFJila8hFptvygOp19OSDSrUIlcq6PeHlfNQtXjs2VFREQydQNE2cdLe68Nh5F5V4HX20C449MKNWK4ybwmFrnX-o9KgERaP1rjrCcWYrZ-lK8TquHti9XMfSaj71eDkfPVOLyCOe1_zBEEH8NRFtN2OcVQWJFPy09rz1yw7a1YARdsU4DukrhWvWcVxIad8ygA
>
< HTTP/2 200
< content-type: application/json; charset=utf-8
< content-length: 412
< connection: keep-alive
< x-ratelimit-limit: 300
< x-ratelimit-remaining: 299
< x-ratelimit-reset: 1502250163
< vary: Accept-Encoding,User-Agent
<
{"account_id":1, ...(略) }
offline_accessスコープについて
リソースオーナー不在時(オフライン)でも、永続的なAPIアクセスを可能にするスコープが offline_access
スコープです。
このスコープを指定しない場合、リソースオーナーが常にクライアントをオンラインで利用する前提であるため、14日が経過するとリフレッシュトークンによるアクセストークンの更新ができなくなります。
これはデフォルトの挙動であり、一般的にはこちらの使い方を推奨しますが、Botなどリソースオーナー不在時には向いていません。
その場合は、offline_access
スコープが利用可能です。
offline_access
スコープを指定した場合、リフレッシュトークンは、認可を失効されるまで期間に無関係に有効となります。
その間はリソースオーナーが不在でも、アクセストークンを更新できます。
オンライン時と比べて長期間リフレッシュトークンを利用することになるため、セキュリティリスクを十分に考慮した上で利用してください。
PKCEについて
PKCE(Proof Key for Code Exchange by OAuth Public Clients)は、パブリッククライアントにおける認可コード横取り攻撃(authorization code interception attack)を対策するために考えられたOAuth 2.0拡張仕様です。
パブリッククライアントが認可コードフローを実行した場合、認可コードが、攻撃者のアプリケーションによって横取りされる可能性がありますが、PKCEを利用するとこの問題を対策できます。また、いずれのクライアントタイプに関わらずPKCEを利用できますが、パブリッククライアントは、セキュリティ強化のためにPKCEが必須となります。
Appendix
A. スコープ一覧
太文字:いくつかのスコープを集約したスコープ
Name | API | Description |
---|---|---|
offline_access |
|
永続的なAPIアクセスの許可 |
users.all:read |
|
自分のアカウントに紐づく情報の取得 |
users.profile.me:read |
|
自分のプロフィール情報の取得 |
users.status.me:read |
|
自分の未既読数の取得 |
users.tasks.me:read |
|
自分のタスク一覧の取得 |
rooms.all:read_write |
|
チャットルームに紐づくメッセージ・タスク・ファイル・概要・メンバー情報の操作/取得 |
rooms.all:read |
|
チャットルームに紐づくメッセージ・タスク・ファイル・概要・メンバー情報の取得 |
rooms.all:write |
|
チャットルームに紐づくメッセージ・タスク・ファイル・概要・メンバー情報の操作 |
rooms:write |
|
チャットルームの作成と参加しているチャットルームの削除 |
rooms.info:read |
|
自分が参加しているチャットルーム一覧の取得 |
rooms.info:write |
|
自分が参加しているチャットルーム情報の更新 |
rooms.members:read |
|
自分が参加しているチャットルームのメンバーの取得 |
rooms.members:write |
|
自分が参加しているチャットルームのメンバーの追加/削除/権限変更 |
rooms.messages:read |
|
自分か参加しているチャットルームのメッセージ取得 |
rooms.messages:write |
|
自分が参加しているチャットルームへのメッセージ投稿 |
rooms.tasks:read |
|
自分が参加しているチャットルームのタスク取得 |
rooms.tasks:write |
|
自分が参加しているチャットルームでタスクを作成 |
rooms.files:read |
|
自分が参加しているチャットルームにアップロードされているファイル情報を取得 |
rooms.files:write |
|
自分が参加しているチャットルームへのファイルのアップロード |
contacts.all:read_write |
|
自分のコンタクト、及びコンタクト承認依頼情報の取得/操作 |
contacts.all:read |
|
自分のコンタクト、及びコンタクト承認依頼情報の取得 |
contacts.all:write |
|
自分あてのコンタクト承認依頼情報を操作 |
B.認可時に発生するエラーの一覧
エラーコード (error_code) | エラーの説明 (error_description) | 補足 |
---|---|---|
1001 | response_type parameter is missing. | コンセント画面を表示するときに、response_typeパラメーターが指定されていないケース。 |
3001 | The resource owner denied the request. | リソースオーナーがログイン画面もしくはコンセント画面で認可を拒否したケース。 |
4001 | token response type is not supported. | コンセント画面を表示するときに、サポートしていないresponse_typeが指定されたケース。 |
4002 | foo response type is unknown. | コンセント画面を表示するときに、未定義のresponse_typeが指定されたケース。 |
5001 | Scope is missing. | スコープが指定されていないケース。 |
5002 | The scope is unknown. | 未定義のスコープが指定されたケース。 |
5003 | The scope is unregistered. | 不正なスコープを指定されたケース。 |
11000 | client_id is missing. | client_idが指定されていないケース。 |
12000 | The client ID client_id is unknown. | 指定されたclient_idが不明なケース。 |
13000 | redirect_uri is missing. | redirect_uriが指定されていないケース。 |
14000 | The redirect URI is malformed. | redirect_uriのフォーマットが不正なケース。 |
15000 | The redirect URI is unregistered. | redirect_uriが登録されていないケース。 |
16000 | reserved authorization request is not found or already timed out. | 予約済みの認可リクエストが見つからないか、すでにタイムアウトになっているケース。 ※ 再度お試しください |
18000 | code_challenge_method is unsupported. | サポートされていないcode_challenge_methodが指定されたケース。 |
19000 | code_challenge is malformed. | code_challengeが不正なケース。 |
20000 | code_verifier is malformed. | code_verifierが不正なケース。 |
Updated over 1 year ago