Postmanを使ってSalesforce APIにアクセスする (特別なシナリオの OAuth 2.0 ユーザ名パスワードフローの場合)

ご存知の通り**前置きが長い**です。`Postman`でSalesforceの認証を行う設定をとっとと見せろという方は[Postman の認証用 API接続設定はこうだ](https://qiita.com/sho7650/items/60da77b5532d2d81e01c#postman-%E3%81%AE%E8%AA%8D%E8%A8%BC%E7%94%A8-api%E6%8E%A5%E7%B6%9A%E8%A8%AD%E5%AE%9A%E3%81%AF%E3%81%93%E3%81%86%E3%81%A0)へどうぞ。接続アプリケーションを忘れずにね。

さて、便利ですね "[Postman](https://www.postman.com/)" 便利です。
使えば使うほど、ああ、これだけで良かったみたいにもなります。

さて、われらがノーコード・ローコードの代表 [Salesforce](https://developer.salesforce.com/ja/) さんですが、[APIサービス](https://help.salesforce.com/articleView?id=integrate_what_is_api.htm&type=5)としても優れています。SOAP/XML, REST/JSON|XMLといった一般的なデータ送受のみならず、カスタマイズされた構成をメタデータをやり取りできたり、BayeuxベースのStreaming APIも利用できます。

このふんだんなAPIサービスを利用するための[Workbench](https://workbench.developerforce.com/)という専用のツールもあります。これだけで、ほとんどすべてのAPIをテストしたりできて、ひじょーに便利です。APIでアクセス可能かどうかの検証や、APIコールの結果を実際にRAWデータで確認もできます。とはいえ、あくまでもAPIアクセス検証ツール的なものなので、独自のテストやルーチンを回すには向きませんね。ちょろっと使うには最高なんです。

ということで、"[Postman](https://www.postman.com/)" です。はいきた。これで利便性が高まるのは確定です。どのようにすれば"[Postman](https://www.postman.com/)"から`Salesforce`へアクセスできるか。今日は「Postmanでusername/password でアクセスしてみた編」です。

# まずはともかく Salesforce で「接続アプリケーション」を作ろう

`Salesforce`は、特定の外部アプリケーション以外のAPIクライアントを受け付けてくれません。ついでにいうと、標準状態だと、Salesforceから外部へも接続できません。[リモートサイト](https://qiita.com/hrk623/items/942102988a7d8ce08f75#%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88%E3%82%B5%E3%82%A4%E3%83%88%E3%81%AE%E8%BF%BD%E5%8A%A0)を使って定義しなければなりません。

[接続アプリケーション](https://help.salesforce.com/articleView?id=connected_app_create.htm&type=5)の作り方は、こちらに詳しいです。今回のようにAPIで接続する場合には、[API インテグレーション用の OAuth 設定の有効化](https://help.salesforce.com/articleView?id=connected_app_create_api_integration.htm&type=5)が必要です。

実際に設定する画面は、次のとおりです。`赤い線`のついてる必須項目だけ入力してあげればよいということと、「OAuth 設定の有効化」にチェックをつけることです。

<img width="1253" alt="Screen Shot 2020-08-06 at 15.48.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/b9ac2fb8-a93b-a85d-1225-f565dd300045.png">

ここで、忘れずに設定しなければならないことはもう一つ。実際に利用するAPIにあわせて「選択した OAuth 範囲」を定義することです。「full」でええやんけと思われるかもしれませんが、次の点は注意ポイントです。

> full は更新トークンを返しません。更新トークンを取得するには、refresh_token の範囲を明示的に要求する必要があります。

まぁ何でもかんでもじゃなくて、必要なものだけにしましょう。

認証を行うための認証フローは多くあり、全ては[OAuth 認証フロー](https://help.salesforce.com/articleView?id=remoteaccess_oauth_flows.htm&type=5)で明記されています。このうち[サーバ間インテグレーション用の OAuth 2.0 JWT ベアラーフロー](https://help.salesforce.com/articleView?id=remoteaccess_oauth_jwt_flow.htm&type=5)や[特別なシナリオの OAuth 2.0 ユーザ名パスワードフロー](https://help.salesforce.com/articleView?id=remoteaccess_oauth_username_password_flow.htm&type=5) などを利用する場合は、`コールバックURL` は不要です。そういった場合は「`https://localhost:8443/RestTest/oauth/_callback`」というような`https`の適当なURLを入れておきましょう。

全部入れたら「保存」です。

# Postman の認証用 API接続設定はこうだ

今回は[特別なシナリオの OAuth 2.0 ユーザ名パスワードフロー](https://help.salesforce.com/articleView?id=remoteaccess_oauth_username_password_flow.htm&type=5)で"[Postman](https://www.postman.com/)"を設定してみます。

Postmanで設定が必要なのは`Body`と`Tests`だけです(もちろんURLもいるんだけど)。

その前に、さっき作成した「接続アプリケーション」を「参照」で開いてみましょう。このような画面が出てきます。重要なのは「コンシューマ鍵」と「コンシューマの秘密」です。コピペの準備をしておきましょう。Summer'20からでしょうか、いずれの項目も`Copy`ってボタンついてます。ありがたい。

<img width="1252" alt="Screen Shot 2020-08-06 at 16.04.28 copy.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/a4847706-3bbc-5145-c364-defe11e54a8f.png">

コピペの準備ができたら、`Postman`を設定します。SalesforceのOAuth認証フローで利用するURLは `https://login.salesforce.com/services/oauth2/token` です。「私のドメイン」を設定して、`login.salesforce.com`からのログインは拒否している場合は、該当のドメインにしましょう。HTTPメソッドは「POST」です。

次に`Body`部分です。`form-data`でも`x-www-form-urlencoded`でも、いずれでも良いので、次の5項目を入れましょう。

```
client_id:
client_secret:
grant_type:password
username:
password:
```

- client_id: 先程の接続アプリケーションで表示されていた「コンシューマ鍵」です
- client_secret: 先程の接続アプリケーションで表示されていた「コンシューマの秘密」です
- grant_type: `password` 固定です。OAuthフローごとに名称が変わります
- username: ログイン時のユーザ名です
- password: ログイン時のユーザのパスワードです。信頼できるIPアドレス外からのアクセスや、2FAが設定されているような場合には、パスワードのあとに[セキュリティトークン](https://help.salesforce.com/articleView?id=user_security_token.htm&type=5)が必要です。認証エラーで「セキュリティトークンが必要です」と言われたらつければよいです。だいたい必要です。

<img width="1043" alt="Screen Shot 2020-08-06 at 16.01.20 copy.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/d99a5e31-ad1d-9db0-f61b-66097cc00213.png">

最後が`Tests`部分です。ここは、認証済みのアクセストークンを再利用しやすいように、ログインが成功したときのアクセストークンを環境変数に保管します。

```
const json = JSON.parse(responseBody)
const ok = responseCode.code === 200

if (ok) {
    pm.globals.set('access_token',json.access_token)
    pm.globals.set('id', json.id)
}
```

<img width="803" alt="Screen Shot 2020-08-06 at 16.01.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/2c04b08e-db1a-be80-9eda-1ae8532785fe.png">

ここまで設定できたら「Send」してみます。うまく設定できていれば、こんな感じで`access_token`を始めとした、いくつかの情報が返却されます。やったね。

<img width="347" alt="Screen Shot 2020-08-06 at 16.24.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/0d886341-6b7d-f314-e026-6b4e5630b6d4.png">

この返り値の中の`access_token`と`id`が環境変数へ保管されています。

これらを使って、実際に認証済みの状態でアクセスするには次のようにします。`URL`になにも考えずに`{{id}}`、`Authorization`の`TYPE`を`Bearer Token`にして、`Token`に`{{access_token}}`とそっと定義します。したらば「Send」です。

<img width="1043" alt="Screen Shot 2020-08-06 at 16.26.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/045dae70-0da6-164d-e096-ccba928e20fb.png">

返却値には、対象ユーザの詳細情報がたくさん表示されているはずです。アクセストークンを使って、ただしくSalesforceのAPIへアクセスできましたね。

こんな感じで、[Salesforce REST API](https://developer.salesforce.com/docs/atlas.ja-jp.api_rest.meta/api_rest/resources_list.htm)へアクセスするテストを実装していってみましょう。