アプリケーションの作成の次のステップ
ここでは「アプリケーションを作成する」で取得したClient ID/Secretを用いて、アクセストークンを取得する手順を紹介します。
freeeではOauth2.0を採用しており、この仕組みにより、アプリケーション利用者はfreeeのIDとパスワードをアプリケーションに教えることなくログイン、アプリケーションを利用することができます。
freeeではAuthorization Code Grantを推奨しています。アクセストークン取得は以下の手順にて行います。
- ユーザーの同意を得て認可コードを取得する
- アプリケーションを利用するユーザーが認可をすることで認可コードを取得することができる
- ユーザーがログインしていなければログイン、複数の事業所に所属していれば選択、データアクセスを確認して許可すると認可コードを取得可能です
- アプリケーションを利用するユーザーが認可をすることで認可コードを取得することができる
- 認可コードとclient id, client secretを利用してアクセストークンを取得する
- あわせてリフレッシュトークンも取得できる
- 有効期限が切れそう、切れたら)リフレッシュトークンを用いてアクセストークンを取得する
- 認可コードの変わりにリフレッシュトークンを利用して新しいアクセストークンを取得する
- 1つのリフレッシュトークンを利用して2度アクセストークンを取得することはできません。アクセストークン取得毎にリフレッシュトークンを保管し、アクセストークンを取得してください。
- 取得している有効なアクセストークンでリソースサーバーにアクセスして必要なデータを取得する
以下で詳細なステップを見ていきましょう。
3.認可コードを取得する
認証用URLはアプリケーション利用者にアクセス権や対象のなる事業所の確認と許可を得るためのURLで、アプリケーションは認可コードを取得するためのきっかけとなる画面です。freeeアプリストアのアプリ管理画面で確認します。
Top > アプリ管理 > アプリ詳細 「基本設定」タブ
- コールバックURLを指定します。コールバックURLは認可コードやアクセストークンを取得できた際に情報をアプリケーションに渡す場として機能、設定します。
- ローカル環境 でテストなどを行う場合は`urn:ietf:wg:oauth:2.0:oob` に設定し、認証用URLにアクセスします。
- アプリケーションを配置しているサーバーがローカル環境ではなく、例えばSpreadsheetなどの場合は必要な値を入れます。
- 変更して下書き保存を行うと認証用URLが変わります。
ブラウザで認可コード取得する場合
1.テストを行う、フローを理解する目的の場合は、ブラウザで認可コードの取得ができます。アプリケーション利用者(freee user, リソースオーナー)が認証用URLにアクセスし、freeeのid, passwordでログインをすると、以下の画面となります。アクセス権とアクセスする事業所を選択したのちに、アプリケーションにアクセスを許可する意思として「許可する」をクリックします。
2.認可コードが表示されます。
アプリケーションからredirect_uriを利用して認可コードを取得する場合
実際に業務で利用する、してもらうアプリケーションを実装する場合は、以下の流れで認可コードを取得します。(ログイン操作、確認についてはブラウザを利用します)
- 利用者がアプリケーションにアクセスしたタイミングで、アクセストークンの取得ができていない場合は以下のようにアプリケーション処理とユーザーアクションを進めます
- アプリケーションからリダイレクトを行うことで認証用URLにアクセスするように導きます。これにより、利用者は認可エンドポイントへアクセスすることになり、上記のブラウザでアクセスする場合と同じ画面(アクセス権、アクセスする事業所)を表示することができます。
- ユーザーがログインできていない場合、認証用URLに遷移した後に
- ユーザーにはfreeeのログイン画面が表示されます
- ユーザーはid/passwordを入れるか、googleアカウントなどでログインします
- ユーザーが複数の事業所所属している場合(そうでない場合は、画面表示されません)
- ユーザーは利用する事業所を選択します
- ユーザーは認可をします
- 「アプリ連携を開始しますか?」の画面でアクセス権を確認し、「許可する」ボタンを押下します
- 認証用URLを具体的なURLで表現すると、以下のようになります。
https://accounts.secure.freee.co.jp/public_api/authorize?response_type=code&client_id={アプリのclient_id}&redirect_uri={アプリのコールバックURL}&state={ランダムな文字列}
&prompt=select_company- アプリストアの基本情報画面で取得や設定ができます
- コールバックURLはエンコードして入れます。
- stateはCSRF対策として、同一のセッションであることを確認するために利用します。リクエストごとにアプリケーション側で生成した十分な長さのランダムな文字列を指定してください
- リクエストヘッダには以下を指定します。
Content-Type:application/x-www-form-urlencoded
- リクエストが成功し、利用者がログインをした上で「許可する」を選択すると(ユーザーがアプリのアクセス権と、アクセス先の事業所を確認、許可すると)、認可コードが発行されます。
- この時、redirect_url に指定された値によって、認可コードのレスポンス先が変わります
HTTP/1.1 302 found Location: {アプリのコールバックURL}?code={認可コード}&state={認証用URLに指定したランダムな文字列}
- クライアント側で認可リクエスト時に指定したstateがリダイレクト時に返却されたstateパラメータと一致しているかチェックを行って下さい。一致していない場合はエラーとして処理をしてください。
- チェックが問題なければ上記レスポンスで得られた認可コードを取得してアクセストークンを取得しましょう
4.アクセストークンを取得する
1.Access Token URLにリクエストを送信する。
これまでに取得したClient ID、Secret、認可コード、コールバックURL(エンコードしたもの)の4点から、アクセストークンを取得します。
curl -i -X POST \
-H "Content-Type:application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "client_id=アプリのClient ID" \
-d "client_secret=アプリのClient Secret" \
-d "code=取得した認可コード" \
-d "redirect_uri=アプリのencodedコールバックURL" \
"https://accounts.secure.freee.co.jp/public_api/token"
2.リクエストレスポンスからアクセストークンを取得する
リクエストが成功すると以下のようなレスポンスが戻ります。レスポンスの中からアクセストークン、リフレッシュトークンを取得します。
取得できたアクセストークンの有効期限は6時間です。
多くのAPIでは、事業所IDを指定してAPIを利用します。下記トークンレスポンスによって返却されたcompany_idを指定してアクセスする必要があるため、company_idをトークンと共に保存して下さい。
{
"access_token": "アクセストークンの文字列",
"token_type": "bearer",
"expires_in": 21600,
"refresh_token": "リフレッシュトークンの文字列",
"scope": "read write"
"company_id": "事業所IDの文字列"
}
※尚、開発者のユースケースによっては、デフォルトで提供される認証用URLの末尾から”&prompt=select_company”を削除して認証を行う場合があります。
このユースケースの詳細についてはfreee APIの使い方-事業所の選択についてをご覧ください。
この場合、アクセストークン取得時のレスポンスは以下のようになります。
{
"access_token": "アクセストークンの文字列",
"token_type": "bearer",
"expires_in": 21600,
"refresh_token": "リフレッシュトークンの文字列",
"scope": "read write"
}
リフレッシュトークンを用いてアクセストークンを取得する
初回は認可コードからアクセストークンを取得しましたが、2回目以降は認可コードの代わりに4.2で取得したリフレッシュトークンを用いてアクセストークンを取得します。リフレッシュトークンには有効期限はありません。
※2023年12月頃より、リフレッシュトークンの有効期限が「有効期限なし」から、「発行後90日間」に変更される予定です。
詳細は以下のお知らせをご確認ください。
【重要】リフレッシュトークンの有効期限の変更
curl -i -X POST \
-H "Content-Type:application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "client_id=あなたのClient ID" \
-d "client_secret=あなたのClient Secret" \
-d "refresh_token=取得したrefresh_token" \
"https://accounts.secure.freee.co.jp/public_api/token"
サンプルコード
Java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.Unirest;
//変数を書き換えて利用します。
String client_id = { あなたのclient_id }
String client_secret ={ あなたのClient Secret };
String redirect_uri = { あなたのencodedコールバックURL }
String code = { 取得した認可コード }
String token_url = "https://accounts.secure.freee.co.jp/public_api/token";
String access_token;
String refresh_token;
//アクセストークンを取得する。
HttpResponse response = Unirest.post(token_url)
.header("Content-Type", "application/x-www-form-urlencoded")
.field("grant_type", authorization_code)
.field("redirect_uri", redirect_uri)
.field("client_id", client_id)
.field("client_secret", client_secret)
.field("code", code)
.asJson();
if (response.getStatus() != 200) {
throw new HttpException(response.getStatusText());
}
//リクエストレスポンスからアクセストークンを取得する。
response = response.getBody();
JSONArray jsonArray = response.getArray();
JSONObject jsonObject = jsonArray.getJSONObject();
access_token = jsonObject.getString("access_token");
refresh_token = jsonObject.getString("refresh_token");
//リフレッシュトークンを用いてアクセストークンを取得する。
HttpResponse response = Unirest.post(token_url)
.header("Content-Type", "application/x-www-form-urlencoded")
.body("grant_type=" + refresh_token + "&
redirect_uri=" + redirect_uri + "&
client_id=" + client_id + "&
client_secret=" + client_secret + "&
refresh_token=" + refresh_token)
.asJson();
Node.js
var request = require("request");
//変数を書き換えて利用します。
var token_url = "https://accounts.secure.freee.co.jp/public_api/token";
var redirect_uri = "あなたのencoedコールバックURL";
var client_id = "あなたのClient ID";
var client_secret = "あなたのClient Secret";
var code = "取得した認可コード";
var access_token = null;
var refresh_token = null;
//アクセストークンを取得する。
var options = {
method: 'POST',
url: token_url,
headers: {
'cache-control': 'no-cache',
'Content-Type': 'application/x-www-form-urlencoded'
},
form: {
grant_type: "authorization_code",
redirect_uri: redirect_uri,
client_id: client_id,
client_secret: client_secret,
code: code
},
json: true
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
//リクエストレスポンスからアクセストークンを取得する。
var response = body;
access_token = response.access_token;
refresh_token = response.refresh_token;
});
//リフレッシュトークンを用いてアクセストークンを取得する。
var options = {
method: 'POST',
url: token_url,
headers: {
'cache-control': 'no-cache',
'Content-Type': 'application/x-www-form-urlencoded'
},
form: {
grant_type: "refresh_token",
redirect_uri: redirect_uri,
client_id: client_id,
client_secret: client_secret,
refresh_token: refresh_token
},
json: true
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
//リクエストレスポンスからアクセストークンを取得する。
var response = body;
access_token = response.access_token;
refresh_token = response.refresh_token;
});
以上でアクセストークンの取得は完了です。
続いて、アクセストークンを用いてAPIのGET/POSTリクエストを行いましょう。
(補足)freee APIにおけるアクセストークンの発行単位と2つの権限について
freee APIでは、ユーザー単位でアクセストークンを発行します。
認証用URLの末尾で&prompt=select_companyを指定し、事業所選択機能を有効にして認可リクエストを行った場合は、認可画面でユーザーが選択した事業所に対してのみアクセスが可能となります。
認証用URLの末尾から&prompt=select_companyを削除し、複数の事業所に所属するユーザーがアプリの認可を行うと、そのユーザーが所属する全ての事業所に対してアクセスが可能となります。
事業所選択機能について、詳しくはfreee APIの使い方-事業所の選択についてをご覧ください。
アプリがアクセスできるリソースは、アプリに設定されているアクセス権と、アプリを利用するユーザーに設定されている権限によって異なります。この権限はプロダクトごとに設定できます。それぞれ以下の通りです。
- アプリに設定されているアクセス権
- アプリごとに設定する、アプリがどのリソースにアクセス可能かの権限
- アプリストアでアプリ開発者が設定する。
- freeeプロダクトでユーザーに設定されているアクセス権限
- freeeプロダクト内で設定されている、ユーザーがどのリソースにアクセス可能かの権限
- freeeプロダクト内で事業所の管理者ユーザーが設定する。