OAuth

OAuth2.0について

仕様

認可フロー

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

機能

現在公開中のすべてのチャットワークAPIをご利用いただけます。

クライアントプログラムからチャットワークAPIを利用する方法

1.クライアントの登録

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

項目 必須 説明
クライアント名 クライアントの名前です。
リダイレクトURI 最低1つ、最大で5つまで登録できます。httpsである必要があります。
スコープ 最低1つは登録が必要です。各チャットワークAPIを叩くために必要なスコープは、Appendixスコープ一覧を参照してください。

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スコープ一覧

state 文字列

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

例. 343ab3341331218786ef

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

例.コンセント画面を表示するための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

認可コードの発行

コンセント画面においてリソースオーナーが「許可」ボタンを押すと認可コードが発行され、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でエンコードしてください。これらの情報はクライアント管理画面から確認できます。

例.
Authorization: Basic THZvMFl1OO==
リクエストボディのフォーマット
application/x-www-form-urlencoded
ボディパラメータ
認可コードから発行する場合
パラメータ名 指定する値 必須
grant_type 文字列 authorization_codeを指定してください。
code 文字列 認可許可ボタンを押して取得した認可コードを指定してください。
redirect_uri 文字列

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

例. https://example.com/callback

リフレッシュトークンを使って再発行する場合
パラメータ名 指定する値 必須
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'  \
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": "1501138041000",
  "refresh_token": "86277ab4fd9d111bd3225215d96d6
22c9ae6810d82cd6d0e9530bf35adda67ab7d3c24e2a0
052e9d3b442ce212ca17ecf07ddbd8c3477aa3abde15e4ebcf7b53",
  "scope": "rooms.all:read_write"
}

4.チャットワークAPIへのアクセス

リクエスト

チャットワークAPIへリクエストを送る際に、従来のチャットワーク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

レスポンス

チャットワークAPIの各エンドポイントドキュメントを参照してください。

エラー

アクセストークンが失効している場合や不正な場合にはWWW-Authenticateヘッダーにエラー情報をセットされます。

例.アクセストークンが失効している場合
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="invalid_token",
error_description="The access token expired"
例.curlコマンドでチャットワーク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: 100
< X-RateLimit-Remaining: 99
< X-RateLimit-Reset: 1502250163
< Vary: Accept-Encoding,User-Agent
<
{"account_id":1, ...(略) }

Appendix

A.スコープ一覧

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

Name API Description
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: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: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 自分が参加しているチャットルームにアップロードされているファイル情報を取得
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. client_idのフォーマットが不正なケース。
15000 The redirect URI is unregistered. client_idが登録されていないケース。