安心してください。PostmanはOAuth2.0の自動トークンリフレッシュをサポートしてますよ

# はじめに

こんにちは。一昨日の2023年7月4日に開催した日本で初めての[Postman Meetup](https://postman.connpass.com/event/286626/)が無事に終了しました🎉。現地とオンラインのハイブリッドでの開催で、運営メンバー兼発表者として参加させていただきましたが、ご参加いただいた皆さまからPostmanにさまざまな感想・フィードバックをいただきとても実りある会となりました。ご参加いただいた皆様には改めて感謝申し上げます。

https://postman.connpass.com/event/286626/

さて、表題の件ですが、Meetupの懇親会にて、参加者の方からPostmanがOAuth2.0の自動トークンリフレッシュがBuilt-inでサポートしていることを知らなかったという意見をいただきました。この手軽で便利な機能をより多くの人に知ってもらうべく本記事を書くことにしました。

# OAuth2.0のトークンリフレッシュについて

リフレッシュトークンは、ざっくり言うとアクセストークンを発行するためのトークンであり、通常アクセストークンより有効期間が長い設定となっています。このリフレッシュトークンを活用したアクセストークン取得のことをトークンリフレッシュと呼びます。

以下、OAuth 2.0のトークン取得フローを簡単に説明します。

1. クライアントは、認証サーバーによる認証と認可付与を行い、アクセストークンをリクエストします。認証サーバーはクライアントを認証し、認可付与を検証し、有効であればアクセストークンとリフレッシュトークンを発行します（下図のAとB）

2. クライアントはアクセストークンを提示して、リソースサーバーに対して保護されたリソースのリクエストを行います。リソースサーバーはアクセストークンを検証し、有効であればリクエストを処理します。これは、アクセストークンの有効期限が切れるまで繰り返されます。もし、アクセストークンの有効期限が切れている場合は、リソースサーバーは無効なトークンエラーを返します。そうなると、トークンのリフレッシュが必要になります（下図のC、D、E、F）

3. クライアントは、認証サーバーによる認証とリフレッシュトークンを提示して、新しいアクセストークンをリクエストします（なお、クライアントの認証要件は、クライアントの種類と認証サーバーのポリシーに基づきます）。 認証サーバーはクライアントを認証し、リフレッシュトークンを検証し、有効であれば新しいアクセストークン（および必要に応じて新しいリフレッシュトークン）を発行します（下図G,H）

![Screenshot 2023-07-06 at 8.23.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103420/65d9d8bd-0d76-9a29-b2a4-6b0dc71d40f3.png)
> 参照: [RFC 6749 - Refreshing an Expired Access Token](https://www.rfc-editor.org/rfc/rfc6749#section-1.5)

トークンリフレッシュは上記の3（イメージのG,H）にあたります。

参考までに、[Spotify API](https://developer.spotify.com/)のOAuth2.0リフレッシュトークンのリクエストをcURLでやるとすると次のようになります。

```bash
curl -X POST
'https://accounts.spotify.com/api/token'
 -H 'Authorization: Basic {base64_encode({client_id}:{client_Secret})}'
 -H 'Content-Type: application/x-www-form-urlencoded'
 -d 'grant_type=refresh_token'
 -d 'refresh_token={refresh_token}'
```

また、JavaScriptでは次のようになります。

```js
  var refresh_token = req.query.refresh_token;
  var authOptions = {
    url: 'https://accounts.spotify.com/api/token',
    headers: { 'Authorization': 'Basic ' + (new Buffer.from(client_id + ':' + client_secret).toString('base64')) },
    form: {
      grant_type: 'refresh_token',
      refresh_token: refresh_token
    },
    json: true
  };
  request.post(authOptions, function(error, response, body) {
    if (!error && response.statusCode === 200) {
      var access_token = body.access_token;
      res.send({
        'access_token': access_token
      });
    }
  });
```
> 参考: https://developer.spotify.com/documentation/web-api/tutorials/code-flow

APIのテストをする際に、自前のAPIであれば開発段階に認証処理をコメントアウトしてテストすることは可能ですが、外部APIとなると認証処理を事前実行しなければいけません。軽くテストするのに上記のようにスクリプト化したりプログラムをモジュール化してテストコードに組み込むのは面倒ですよね。

# PostmanのOAuth2.0 自動トークン・リフレッシュ機能

ようやく本題です。PostmanはOAuth2.0の自動トークンリフレッシュ機能が利用可能です。
もともとOAuth2.0はサポートしてましたが、取得したアクセストークンのリフレッシュができず、利用ユーザーから多くのサポートリクエストを頂き、ついに2023年2月、自動トークンリフレッシュ機能が利用可能になりました。

https://blog.postman.com/oauth-2-0-token-refresh-and-id-token-support/

PostmanのOAuth 2.0のアクセストークン取得の設定は、リクエストメニューのAuthenticationタブから行います。Postmanでアクセストークン取得に必要な準備ができたら下記イメージの「Get New Access Token」ボタンを押すとアクセストークンが取得できます。PostmanのOAuth 2.0設定について初めての方は[こちらのページ](https://learning.postman.com/docs/sending-requests/authorization/oauth-20/)が参考になります。

![Screenshot 2023-07-06 at 11.25.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103420/bc210fb2-6300-1ea3-6825-3ac9ac202951.png)

既に取得したアクセストークンが有効期限切れになると、下図イメージのようにToken expiredになります。ここで隣の「Refesh」をクリックすることでトークンが更新されます。

さらに、下図イメージの「Auto-refesh token」オプションを有効化すると、有効期限が切れたトークンがリクエスト送信前に自動で更新されるようになります。たったこれだけで、面倒なトークン更新作業から開放されます。最高ですよね？ 

![Screenshot 2023-07-06 at 9.34.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103420/98ce4b34-4f12-e96b-8c27-4ba68fc35121.png)

:::note warn
**リフレッシュリクエストのデフォルトでBasic認証ヘッダー付与される挙動とその対応策 (2024/02追記)**

現時点（2024年２月時点）では、[こちらのIssue](https://github.com/postmanlabs/postman-app-support/issues/11668)でも報告されているように手動・自動共にリフレッシュリクエスト（リフレッシュトークンを利用してトークンをリフレッシュするためのリクエスト）において、デフォルトでBasic認証ヘッダーが付与される挙動となっており、意図せずリクエストが失敗するという問題があります。

![Screenshot 2024-02-26 at 10.31.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103420/b1d5abfb-0bdd-c897-20ba-340df45f870c.png)

この問題のワークアラウンドとして、issueコメントで言われているように、OAuth2.0の詳細設定のリフレッシュリクエストにclient_idパラメータの設定を追加した後に、新しいトークンを取得することで、このBasic認証ヘッダーが付与されなくなります。繰り返しになりますが、必ず、詳細設定にclient_idパラメータ追加した後に、新しいトークンを取得するようにしてください。詳細設定を追加しただけでは変わらずBasic認証ヘッダーが付与されるので。

![Screenshot 2024-02-26 at 10.49.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103420/af90b200-3ac3-4ebe-2ae2-306a1f9e2e07.png)
:::

ちなみに、Postmanも2023年2月にサポートが開始される前は、OAuth2.0のトークンリフレッシュを自前で実施する必要がありました。以下の記事では、Postmanのpre-requestスクリプトを使ってOAuth2.0トークンをリフレッシュする方法をまとめています。なお、今回紹介した自動リフレッシュ機能は、CLIツールであるPostman CLIやNewman、またスケジュール実行やPostmanモニターではサポートされていないため、これらを使ってテスト自動化を行う場合には、このpre-requestスクリプトのアプローチが有効な手段となります。

https://qiita.com/yokawasa/items/f92b2fc5fcff47856912


というわけで、PostmanのOAuth2.0の自動トークンリフレッシュ機能、ご存知なかった人はこれを機にお使いください。

現場からは以上です。