OAuth

OAuth2.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_token String 有効期間は30分間。
refresh_token String 有効期間は14日間。(ただし変更の可能性あり)
token_type String Bearer
expires_in Int トークンの有効期間。(秒)
scope String
error String "invalid_grant" エラーのときに返るフィールド。
error_description String エラーのときに返るフィールド。
error_uri String エラーのときに返るフィールド。現在常に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 THZvMFlOOTJnYTVrUDphYmNkZWZnaGlqa2xu
bW9wcXJzdHV2d3h5ejAxMjM0NTY3ODk=
> 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": "eyJjdHkiOiJKV1QiLCJ0eXAiOiJKV1QiL
CJhbGciOiJSUzI1NiIsImtpZCI6ImlOUVh0dFR2RHZhcDVkSW
pGQzA5ZHZadHFXaGQ2WmFRb2pKenVuUS1vV28ifQ.eyJh
dWQiOiJodHRwczovL2FwaS5jaGF0d29yay5jb20iLCJzdWIi
OiIzIiwiYWNjb3VudF9pZCI6IjMiLCJzY29wZSI6WyJhbGwiXS
wiaXNzIjoiaHR0cHM6Ly9vYXV0aC5jaGF0d29yay5jb20iLC
JleHAiOjE1MDExMzgwNDEsImlhdCI6MTUwMTEzNzE0MSw
ianRpIjoiOTcwNDAwOWItNTdlNi00NDU5LTg5NzMtNjc3Zm
M5YjA5MjgyIiwiY2xpZW50X2lkIjoiTHZvMFlOOTJnYTVrUCJ9.
BIS8QvyTHz7KK_fnmvc0fa8NQDOWy7v8Ni0LvLyuROE5UEi
7l_HxDT8tHLTQLELIm3jOw4SiW94KPYwduRL467vJ2j2eNT
-zTkCXtEN8pxbA0HtnBrtCcp0dRJEMnfBegzkoAe8BTB6gee
3rrXy6sQcLb19WBrrHNbjICFL0--SG3IvPanOzABqiNMqfScn
asTtj7xtIaNpbxf8LDIH3EF150Iif4BqSczJr-XppBTBYuP32Ul
BnRlQOXvXqymGijQXgqDOo3LLFY_k62OoPYAQ3UXkaum8
6Al-DJM6iC-043kBINbYLLPo0uwwsolmjRDG5zBzPC0GtcjXiLy4Gqg",
  "token_type": "Bearer",
  "expires_in": 1800,
  "refresh_token": "86277ab4fd9d111bd3225215d96d6
22c9ae6810d82cd6d0e9530bf35adda67ab7d3c24e2a0
052e9d3b442ce212ca17ecf07ddbd8c3477aa3abde15e4ebcf7b53",
  "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 eyJjdHkiOiJKV1QiLCJ0eXAiOiJKV1
QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImlOUVh0dFR2RHZhcDVkSWpGQz
A5ZHZadHFXaGQ2WmFRb2pKenVuUS1vV28ifQ.eyJhdWQiOiJodHR
wczovL2FwaS5jaGF0d29yay5jb20iLCJzdWIiOiIxNzMiLCJhY2NvdW5
0X2lkIjoiMTczIiwic2NvcGUiOlsiYWxsIl0sImlzcyI6Imh0dHBzOi8vb2F1
dGguY2hhdHdvcmsuY29tIiwiZXhwIjoxNTAyMjUxNDU4LCJpYXQiOjE1
MDIyNDk2NTgsImp0aSI6IjRlNzg5ZTAzLTk2NjAtNDc4MC1hYThkLTV
mZjk2YmU0MzMyNSIsImNsaWVudF9pZCI6Ikx2bzBZTjkyZ2E1a1AifQ.
Y14Sr0SmtgwLegwWPMeQlPut2XmP74y3QdupCAN7Hc5Id10Qvgq-
csuYVxxAYStqZUO4sZ_j9SeE7-rqhuNowDMwqVaTGfDvAvtQLitPKD
Ub2g6x87c-lfffkJkIiL1xcH3lHrmQkBa_H81-_a3VFJila8hFptvygOp1
9OSDSrUIlcq6PeHlfNQtXjs2VFREQydQNE2cdLe68Nh5F5V4HX20C4
49MKNWK4ybwmFrnX-o9KgERaP1rjrCcWYrZ-lK8TquHti9XMfSaj71e
DkfPVOLyCOe1_zBEEH8NRFtN2OcVQWJFPy09rz1yw7a1YARdsU4
DukrhWvWcVxIad8ygA' \
'https://api.chatwork.com/v2/me'
> GET /v2/me HTTP/1.1
> Host: api.chatwork.com
> Accept: */*
> Authorization: Bearer eyJjdHkiOiJKV1QiLCJ0eXAiOiJKV1QiLCJ
hbGciOiJSUzI1NiIsImtpZCI6ImlOUVh0dFR2RHZhcDVkSWpGQzA5Z
HZadHFXaGQ2WmFRb2pKenVuUS1vV28ifQ.eyJhdWQiOiJodHRwc
zovL2FwaS5jaGF0d29yay5jb20iLCJzdWIiOiIxNzMiLCJhY2NvdW50
X2lkIjoiMTczIiwic2NvcGUiOlsiYWxsIl0sImlzcyI6Imh0dHBzOi8vb2F1
dGguY2hhdHdvcmsuY29tIiwiZXhwIjoxNTAyMjUxNDU4LCJpYXQiOjE
1MDIyNDk2NTgsImp0aSI6IjRlNzg5ZTAzLTk2NjAtNDc4MC1hYThkL
TVmZjk2YmU0MzMyNSIsImNsaWVudF9pZCI6Ikx2bzBZTjkyZ2E1a1
AifQ.Y14Sr0SmtgwLegwWPMeQlPut2XmP74y3QdupCAN7Hc5Id10
Qvgq-csuYVxxAYStqZUO4sZ_j9SeE7-rqhuNowDMwqVaTGfDvAvtQ
LitPKDUb2g6x87c-lfffkJkIiL1xcH3lHrmQkBa_H81-_a3VFJila8hFpt
vygOp19OSDSrUIlcq6PeHlfNQtXjs2VFREQydQNE2cdLe68Nh5F5V4
HX20C449MKNWK4ybwmFrnX-o9KgERaP1rjrCcWYrZ-lK8TquHti9X
MfSaj71eDkfPVOLyCOe1_zBEEH8NRFtN2OcVQWJFPy09rz1yw7a1
YARdsU4DukrhWvWcVxIad8ygA
>
< 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スコープです。

このスコープを指定しない場合、リソースオーナーが常にクライアントをオンラインで利用する前提であるため、ある一定期間を過ぎるとリフレッシュトークンによるアクセストークンの更新ができなくなります。
これはデフォルトの挙動であり、一般的にはこちらの使い方を推奨しますが、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 自分のプロフィール情報の取得
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 自分あてのコンタクト承認依頼情報を操作

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. 未定義のスコープが指定されたケース。
11000 `client_id` is missing. 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が登録されていないケース。
18000 `code_challenge_method` is unsupported. サポートされていないcode_challenge_methodが指定されたケース。
19000 `code_challenge` is malformed. code_challengeが不正なケース。
20000 `code_verifier` is malformed. code_verifierが不正なケース。