CData Software Blog

クラウド連携のCData Software の技術ブログです。

Postman Pre-Request Script を使って OAuth Access Token の Refresh を自動で行う

f:id:sugimomoto:20210903093317p:plain f:id:sugimomoto:20210902221625p:plain こんにちは。CData Software Japan リードエンジニアの杉本です。

久しぶりに趣味のPostmanネタです。

www.postman.com

API コラボレーションツール Postman の良いところの一つといえば、様々な認証アプローチをUI上で手軽に指定できる点かなーと思います。

例えば、OAuth(1.0・2.0問わず) であれば、UI上でClient Idや Client Secretを指定するだけで簡単にAccess Tokenを取得して、APIリクエスト・検証が実施できます。

learning.postman.com

ただ、ちょっと面倒なのは Refresh は自動で行ってくれないという点です。

そこで今回は自動的にTokenをリフレッシュしてくれるScriptの書き方を紹介したいと思います。

ちなみに応用すれば、OAuth だけでなく、独自のAPI Token機構で事前に期限付き Tokenを引き換える必要があるAPIも同じように対応できます。

国内のAPIだと、クラウドサインAPIなどは、予めClientIdを元に期限付きのTokenを取得する機構なので、応用できますね。

help.cloudsign.jp

Pre-Request Script について

まず、今回大事になる要素はPostmanの「Pre-Request Script」という機能です。

learning.postman.com

Postman で APIリクエストを実行する直前にこの「Pre-Request Script」で登録しておいたScriptを差し込む、つまり前処理をすることができるようになります。

f:id:sugimomoto:20210902221305p:plain

JavaScriptベースになっているので結構手軽に書けるのではないかなーと思います。

例えばクエリパラメータやヘッダー情報を操作したりすることもできますね。

今回はこの機能を使って、事前にCollection変数に登録しておいたAccess Tokenをリフレッシュするような機能を実現します。

Tokenのリフレッシュを行うサンプルコード

今回は実際のAccess Tokenエンドポイントを使うのも汎用性が無いなと思ったので、Postman Echoで擬似的な表現を行いました。

www.postman.com

うまく対象のOAuth に読み替えながら、実装してみてください。

使い方としては、まず予め対象となる Postman Collectionを作成しておいて、OAuthに必要なClientIdやClientSecretを登録しておきます。

f:id:sugimomoto:20210902221313p:plain

あとは、以下のようなScriptを「Pre-request Script」のところに貼り付けます。

// 前回実行時間を環境変数から取得。Date型に変換・無い場合は古い日付を設定
var tokenDate = new Date(2010,1,1);
var tokenTimestamp = pm.collectionVariables.get("TokenTimestamp");
if(tokenTimestamp){
  tokenDate = Date.parse(tokenTimestamp);
}


// Tokenの期限切れの時間を環境変数から取得:無い場合は対象Tokenの期限切れ時間を指定
var expiresInTime = pm.collectionVariables.get("ExpiresIn");
if(!expiresInTime){
    expiresInTime = 36000;
}

// Tokenの取得で必要になるclientid・clientsecretを環境変数から取得
var clientId = pm.collectionVariables.get("clientid");
var clientSecret = pm.collectionVariables.get("clientsecret");

// ExpiresInTime以内であれば、リフレッシュはしない。
if((new Date() - tokenDate) >= expiresInTime) 
{
   pm.sendRequest({
      url:  'https://postman-echo.com/get?access_token=your_token' + Date.now() + '&expires_in=36000', 
      method: 'GET',
      header: {
        'Accept': 'application/json',
        'Content-Type': 'application/x-www-form-urlencoded',
      },
      body:'grant_type=client_credentials&clientid=' + clientId + '&clientsecret='+clientSecret
  }, function (err, res) {
        pm.collectionVariables.set("Token", res.json().args.access_token);
        pm.collectionVariables.set("TokenTimestamp", new Date());        
        pm.collectionVariables.set("ExpiresIn", res.json().args.expires_in);        
  });
}

Collectionの変数には「pm.collectionVariables.get("Name")」で取得、「pm.collectionVariables.set("Name","Value")」で設定を行うことができます。

learning.postman.com

Pre-Request Script は JavaScript ベースですが、APIリクエストはPostman組み込みの「pm.sendRequest」関数を利用します。

第1引数で、リクエストのMethodやURL、Header、Bodyを指定し、第2引数のデリゲートメソッドでレスポンスの処理を書きます。

learning.postman.com

これで、AccessTokenを取得し直して、Collection変数に最新のAccessTokenを常に格納するようにしています。

おわりに

結構API検証を行うときに使う機会が多かったので、まとめてみました。

他にも署名処理などを書いたことがあったので、いずれまとめてみたいと思います。