OAuth 2.0について

仕様

認可フロー

RFC6749で定義されている認可フロー(Authorization Grant)のうち、Authorization Code Grantにのみ対応しています。

機能

現在公開中の全てのChatwork APIをご利用いただけます。

クライアントプログラムからChatwork APIを利用する方法

1.クライアントの登録

OAuthクライアント作成画面よりクライアント登録を行ってください。
クライアントの情報として、下記の項目を登録します。

項目必須説明
クライアント名クライアントの名前です。
クライアントタイプクライアントの種別です。
項目 必須 説明
クライアント名 クライアントの名前です。
クライアントタイプ

クライアントの種別です。

コンフィデンシャルクライアント
クレデンシャルを安全に秘匿できるサーバーアプリケーション上でのOAuthクライアントとして利用されることを想定しています。

パブリッククライアント
iOS/AndroidアプリやJavaScriptなどの、クレデンシャルを安全に秘匿できないフロントエンドアプリケーション上でのOAuthクライアントとして利用されることを想定しています。

リダイレクトURI

最低1つ、最大で5つまで登録できます。

コンフィデンシャルクライアント
https://から始まるURIを登録できます。

パブリッククライアント
http://以外から始まるURIを登録できます。

スコープ 最低1つは登録が必要です。各Chatwork APIを叩くために必要なスコープは、Appendix - スコープ一覧を参照してください。
ただし、offline_accessを利用できるのはコンフィデンシャルクライアントのみです。

2.認可コード(Authorization Code)の取得

認可コードを取得するためには、Webブラウザーでコンセント画面にアクセスする必要があります。

コンセント画面へのアクセス方法

必要なクエリーパラメーターを設定した上でコンセント画面にアクセスすると、コンセント画面が表示されます。
なおログイン画面が表示された場合は、認証情報を入力してログインすることでリダイレクトされます。

クエリーパラメーター
パラメーター名 指定する値 必須 説明
response_type 文字列 現在はcodeにしか対応していません。
client_id 文字列 クライアントIDを指定してください。
redirect_uri 文字列

クライアント登録時に設定したURIの中から指定してください。

例:https://example.com/callback

複数のredirect_uriを設定している場合は必須ですが、一つしか設定していない場合は任意です。

scope 文字列

スコープをスペース区切りで指定してください。

例:rooms.all:read_write contacts.all:read_write

Appendix - スコープ一覧

offline_accessスコープを指定できるのはコンフィデンシャルクライアントのみです。

state 文字列

CSRF攻撃対策として使う文字列で、リソースオーナーのセッションに紐づけて管理します。リソースオーナーが認可許可または認可拒否を行ったとき、ここでセットしたstateの文字列がクエリーパラメーターにセットされた状態でredirect_uriにリダイレクトされます。
リダイレクト後にセッションに紐づいているstateとクエリーパラメータで渡されたstateの文字列とを比較し、本番運用では必ずCSRF攻撃への対策を行ってください。

例:343ab3341331218786ef

The OAuth 2.0 Authorization Framework 10.12. Cross-Site Request Forgery

code_challenge 文字列

コンフィデンシャルクライアントの場合は任意、
パブリッククライアントの場合は必須。

値は後にトークンエンドポイントで使用するcode_verifierから算出します。

code_verifierの値からSHA-256でハッシュ値をとり、そのハッシュ値をURLセーフなBase64エンコード(パディングなし)を行います。

算出結果の文字列長は43文字から128文字、文字種としては正規表現で[a-zA-Z0-9-._~]+に該当する文字列になります。

code_challenge_method 文字列

コンフィデンシャルクライアントの場合は任意、
パブリッククライアントの場合は必須。

code_challengeを指定する場合は、必ず固定値としてS256を指定してください。

例:コンセント画面を表示するための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にリダイレクトされます。

  • erroraccess_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 文字列

コンセント画面を表示する際にredirect_uriを指定していた場合は、トークンを発行する際にも指定してください。

例:https://example.com/callback

code_verifier 文字列

認可リクエストでcode_challengecode_challenge_methodを指定した場合は必須。

文字列長は43文字から128文字、文字種としては正規表現で[a-zA-Z0-9-._~]+に該当する文字列になります。

リフレッシュトークンを使って再発行する場合(2回目以降)
パラメーター名 指定する値 必須
grant_type 文字列 refresh_tokenを指定してください。
refresh_token 文字列 トークン発行時に生成されたrefresh_tokenの値を指定してください。
scope 文字列

スコープをスペース区切りで指定してください。

例:users.profile.me:read

レスポンス

レスポンスボディのフォーマット
application/json
レスポンスボディ(トークン発行時、再発行時で共通)
正常時
JSONのフィールド名JSONの値の形式必須説明
access_tokenstring有効期間は30分間
refresh_tokenstring有効期間は14日間(offline_accessスコープを含む場合は無期限)
token_typestringBearer
expires_inintegeraccess_tokenの有効期間(秒)
scopestring
エラー時
JSONのフィールド名JSONの値の形式必須説明
errorstringinvalid_grantエラーのときに返るフィールド
error_descriptionstringエラーのときに返るフィールド
error_uristringエラーのときに返るフィールド。常にnull

例: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: 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 -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
自分のアカウントに紐づく情報の取得
users.profile.me:read 自分のプロフィール情報の取得
users.status.me:read 自分の未既読数の取得
users.tasks.me:read 自分のタスク一覧の取得
rooms.all:read_write
  • rooms.all:read
  • rooms.all:write
チャットルームに紐づくメッセージ・タスク・ファイル・概要・メンバー情報の操作/取得
rooms.all:read
  • rooms.info:read
  • rooms.members:read
  • rooms.messages:read
  • rooms.tasks:read
  • rooms.files:read
チャットルームに紐づくメッセージ・タスク・ファイル・概要・メンバー情報の取得
rooms.all:write
  • rooms:write
  • rooms.info:write
  • rooms.members:write
  • rooms.messages:write
  • rooms.tasks:write
  • rooms.files: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
自分のコンタクト、及びコンタクト承認依頼情報の取得/操作
contacts.all:read 自分のコンタクト、及びコンタクト承認依頼情報の取得
contacts.all:write 自分あてのコンタクト承認依頼情報を操作

offline_accessスコープ単体ではChatwork APIを利用することはできませんので、他のスコープと組み合わせて使用してください。

B.認可時に発生するエラーの一覧

エラーコード
(error_code)
エラーの説明
(error_description)
補足
1001response_type parameter is missing.コンセント画面を表示するときにresponse_typeパラメーターが指定されていないケース。
3001The resource owner denied the request.リソースオーナーがログイン画面もしくはコンセント画面で認可を拒否したケース。
4001token response type is not supported.コンセント画面を表示するときにサポートしていないresponse_typeが指定されたケース。
4002<レスポンスタイプ> reponse type is unknown.コンセント画面を表示するときに未定義のresponse_typeが指定されたケース。
5001Scope is missing.スコープが指定されていないケース。
5002The scope is unknown.未定義のスコープが指定されたケース。
5003The scope is unregistered.不正なスコープを指定されたケース。
11000client_id is missing.client_idが指定されていないケース。
12000The client ID <クライアントID> is unknown.指定されたclient_idが不明なケース。
13000redirect_uri is missing.redirect_uriが指定されていないケース。
14000The redirect URI is malformed.redirect_uriのフォーマットが不正なケース。
15000The redirect URI is unregistered.redirect_uriが登録されていないケース。
16000reserved authorization request is not found or already timed out.予約済みの認可リクエストが見つからないか、すでにタイムアウトになっているケース
※ 再度お試しください
18000code_challenge_method is unsupported.サポートされていないcode_challenge_methodが指定されたケース。
19000code_challenge is malformed.code_challengeが不正なケース。
20000code_verifier is malformed.code_verifierが不正なケース。