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

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

例. https://example.com/callback

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

scope 文字列(スペース区切り)

rooms.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 にリダイレクトされます。

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

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

例. https://example.com/callback

code_verifier 文字列

認可リクエストで、code_challenge, code_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の値の形式nullable説明
access_tokenString有効期間は30分間。
refresh_tokenString有効期間は14日間(offline_accessスコープを含む場合は無期限)。
token_typeStringBearer
expires_inIntaccess_tokenの有効期間(秒)。
scopeString

エラー時

JSONのフィールド名JSONの値の形式nullable説明
errorString"invalid_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/1.1
> Host: 127.0.0.1
> Authorization: Basic THZvMFlOOTJnYTVrUDphYmNkZWZnaGlqa2xubW9wcXJzdHV2d3h5ejAxMjM0NTY3ODk=
> Accept: */*
> Content-Length: 199
> Content-Type: application/x-www-form-urlencoded
>

< HTTP/1.1 200 OK
< 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/1.1 401 Unauthorized
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/1.1
> Host: api.chatwork.com
> Accept: */*
> Authorization: Bearer eyJjdHkiOiJKV1QiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImlOUVh0dFR2RHZhcDVkSWpGQzA5ZHZadHFXaGQ2WmFRb2pKenVuUS1vV28ifQ.eyJhdWQiOiJodHRwczovL2FwaS5jaGF0d29yay5jb20iLCJzdWIiOiIxNzMiLCJhY2NvdW50X2lkIjoiMTczIiwic2NvcGUiOlsiYWxsIl0sImlzcyI6Imh0dHBzOi8vb2F1dGguY2hhdHdvcmsuY29tIiwiZXhwIjoxNTAyMjUxNDU4LCJpYXQiOjE1MDIyNDk2NTgsImp0aSI6IjRlNzg5ZTAzLTk2NjAtNDc4MC1hYThkLTVmZjk2YmU0MzMyNSIsImNsaWVudF9pZCI6Ikx2bzBZTjkyZ2E1a1AifQ.Y14Sr0SmtgwLegwWPMeQlPut2XmP74y3QdupCAN7Hc5Id10Qvgq-csuYVxxAYStqZUO4sZ_j9SeE7-rqhuNowDMwqVaTGfDvAvtQLitPKDUb2g6x87c-lfffkJkIiL1xcH3lHrmQkBa_H81-_a3VFJila8hFptvygOp19OSDSrUIlcq6PeHlfNQtXjs2VFREQydQNE2cdLe68Nh5F5V4HX20C449MKNWK4ybwmFrnX-o9KgERaP1rjrCcWYrZ-lK8TquHti9XMfSaj71eDkfPVOLyCOe1_zBEEH8NRFtN2OcVQWJFPy09rz1yw7a1YARdsU4DukrhWvWcVxIad8ygA
>
< HTTP/1.1 200 OK
< 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)を対策するために考えられたOAuth2拡張仕様です。

パブリッククライアントが認可コードフローを実行した場合、認可コードが、攻撃者のアプリケーションによって横取りされる可能性がありますが、PKCEを利用するとこの問題を対策できます。また、いずれのクライアントタイプに関わらずPKCEを利用できますが、パブリッククライアントは、セキュリティ強化のためにPKCEが必須となります。

Appendix

A.スコープ一覧

太文字:いくつかのスコープを集約したスコープ

Name API Description
offline_access
  • 全API
永続的なAPIアクセスの許可
users.all:read
  • users.profile.me:read
  • users.status.me:read
  • users.tasks.me:read
自分のアカウントに紐づく情報の取得
users.profile.me:read
  • GET /me
自分のプロフィール情報の取得
users.status.me:read
  • GET /my/status
自分の未既読数の取得
users.tasks.me:read
  • GET /my/tasks
自分のタスク一覧の取得
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
  • POST /rooms
  • DELETE /rooms/{room_id}
チャットルームの作成と参加しているチャットルームの削除
rooms.info:read
  • GET /rooms
  • GET /rooms/{room_id}
自分が参加しているチャットルーム一覧の取得
rooms.info:write
  • PUT /rooms/{room_id}
自分が参加しているチャットルーム情報の更新
rooms.members:read
  • GET /rooms/{room_id}/members
自分が参加しているチャットルームのメンバーの取得
rooms.members:write
  • PUT /rooms/{room_id}/members
自分が参加しているチャットルームのメンバーの追加/削除/権限変更
rooms.messages:read
  • GET /rooms/{room_id}/messages
  • GET /rooms/{room_id}/messages/{message_id}
自分か参加しているチャットルームのメッセージ取得
rooms.messages:write
  • POST /rooms/{room_id}/messages
  • PUT /rooms/{room_id}/messages/{message_id}
  • DELETE /rooms/{room_id}/messages/{message_id}
  • PUT /rooms/{room_id}/messages/read
  • PUT /rooms/{room_id}/messages/unread
自分が参加しているチャットルームへのメッセージ投稿
rooms.tasks:read
  • GET /rooms/{room_id}/tasks
  • GET /rooms/{room_id}/tasks/{task_id}
自分が参加しているチャットルームのタスク取得
rooms.tasks:write
  • POST /rooms/{room_id}/tasks
自分が参加しているチャットルームでタスクを作成
rooms.files:read
  • GET /rooms/{room_id}/files
  • GET /rooms/{room_id}/files/{file_id}
自分が参加しているチャットルームにアップロードされているファイル情報を取得
rooms.files:write
  • POST /rooms/{room_id}/files
自分が参加しているチャットルームへのファイルのアップロード
contacts.all:read_write
  • contacts.all:read
  • contacts.all:write
自分のコンタクト、及びコンタクト承認依頼情報の取得/操作
contacts.all:read
  • GET /contacts
  • GET /incoming_requests
自分のコンタクト、及びコンタクト承認依頼情報の取得
contacts.all:write
  • PUT /incoming_requests/{request_id}
  • DELETE /incoming_requests/{request_id}
自分あてのコンタクト承認依頼情報を操作

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が指定されたケース。
4002foo response 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 client_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が不正なケース。

Did this page help you?