curlでSalesforceのOAuthアクセストークンを取得してAPIにアクセスする

curlを使用してSalesforceのAPIへのアクセスする方法を紹介します。
Webクライアントを実装する前にアクセストークンの取得からAPIアクセスまで一連のフローをテストしたいときなどに参考にしてください。

# Salesforceの接続アプリケーションの作成

**[設定]**から**[アプリケーションマネージャ]**を開き、**[新規接続アプリケーション]**をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185900/27918e01-2ca4-d529-031a-4cde3b3494d3.png)


**[基本情報]**セクションで**[接続アプリケーション名]**、**[API参照名]**、**[取引先責任者メール]**を入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185900/39fbbe8b-a921-d1d7-ff14-ec0eaed49b3b.png)


**[API]**セクションで**[OAuthの有効化]**をチェックし、**[コールバックURL]**を入力します。続いて**[選択したOAuth範囲]**でOAuthのスコープを設定します。今回はフルアクセスを許可する「full」を追加しました。因みに「full」ではリフレッシュトークンは取得されません。リフレッシュトークンを返すには「refresh_token」も追加してください。スコープについては[Salesforceのヘルプ](https://help.salesforce.com/articleView?id=sso_provider_addl_params_scope.htm&type=5)を参考にしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185900/d19ddd08-8d68-81c6-281f-740d775da5a7.png)


**[保存]**をクリックすると接続アプリケーションが作成され、管理画面に遷移します。
コンシューマ鍵(Client Id)とコンシューマの秘密(Client Secret)をそれぞれコピーしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185900/dcd0215e-ced4-1819-aca0-099eef1a4f04.png)

ここで初期アクセストークンを生成することもできます。以下画面の**[生成]**をクリックするとアクセストークンが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185900/3026761f-efb6-4310-a70d-e33664fe8eab.png)

以下からは、プログラム上で実装可能な認証フローを通してアクセストークンを取得する方法を紹介します。

# アクセストークンの取得

ブラウザとcurlコマンドを使ってアクセストークンを取得します。事前にSalesforceの接続アプリケーションから取得したコンシューマ鍵(Client Id)とコンシューマの秘密(Client Secret)があることを確認してください。

## 認可コードの取得

ブラウザで以下のURLにアクセスします。<クライアントID>には認証情報の作成時に取得したコンシューマ鍵、<リダイレクトURI>には同じく認証情報の作成時に設定したコールバックURLを設定してください。コールバックURLはパラメータに含めるためURLエンコードが必要です。

```
https://login.salesforce.com/services/oauth2/authorize?client_id=<クライアントID>&response_type=code&redirect_uri=<リダイレクトURL(要エンコード)>
```

URL例

```
https://login.salesforce.com/services/oauth2/authorize?client_id=3MVG9G9pzCUSkzZs1Gn30QE5UGV7wM4CsDWh4uf_gCBHaz1DP90A4U50.0afHPSHoKP0SJHy7rkxzl3PduNqX&response_type=code&redirect_uri=https%3A%2F%2Flogin.salesforce.com%2Fservices%2Foauth2%2Fcallback
```

上記URLにアクセスするとSalesforceのログイン画面が表示されますので自身のアカウントでログインしてください。ログインが完了すると下図のようなアプリケーションの認証画面に遷移します。アプリケーション名等を確認し**[許可]**をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185900/e79cd78a-64a5-d510-4545-2f69a8815bd1.png)


認証が完了するとブラウザのURLに認可コードが表示されますのでこれをコピーしておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185900/23214651-f10f-bdd0-fbfd-9a9918ab6740.png)


このとき、認可コードはURLエンコードされていることに注意してください。リクエストボディとして設定する際には末尾の「%3D%3D」は「==」に変換してください。

## OAuthアクセストークンの取得

curlでOAuthアクセストークンを取得します。<認可コード>には前節で取得した認可コード、<クライアントID>、<クライアントシークレット>には認証情報の作成時に取得したコンシューマ鍵とコンシューマの秘密、<リダイレクトURI>には認証情報の作成時に設定したリダイレクトURLを設定してください。

```console
> curl -X POST -d code=<認可コード> -d client_id=<クライアントID> -d client_secret=<クライアントシークレット> -d redirect_uri=<リダイレクトURI> -d grant_type=authorization_code https://login.salesforce.com/services/oauth2/token
```

コマンド例

```console
> curl -X POST -d code=aPrxYXyxzkuBzbgRyajT9k1RTifJQ4p9Zw0P2ynD48OEPr.Zjo6tYYqdbIraZ8UFBJe2ROi8Aw== client_id=3MVG9G9pzCUSkzZs1Gn31QE5UGV7wM4CsDWh4uf_gCBHaz1DP90A4U50.1afTPSHoKP0SJHy7rkxzl3PduNqX -d client_secret=F4D6A09FF692CAEB7046560C4CE5A5B6F4E1133B3C986916F1941DA8D423973D -d redirect_uri=https%3A%2F%2Flogin.salesforce.com%2Fservices%2Foauth2%2Fcallback -d grant_type=authorization_code https://login.salesforce.com/services/oauth2/token 
```

上記コマンドを実行しOAuthアクセストークンのリクエストに成功するとアクセストークンが返ってきます。

```console
> curl -X POST -d code=aPrxYXyxzkuBzbgRyajT9k1RTifJQ4p9Zw0P2ynD48OEPr.Zjo6tYYqdbIraZ8UFBJe2ROi8Aw== client_id=3MVG9G9pzCUSkzZs1Gn31QE5UGV7wM4CsDWh4uf_gCBHaz1DP90A4U50.1afTPSHoKP0SJHy7rkxzl3PduNqX -d client_secret=F4D5A09FF692CAEA7046560C4CE5A5B6F4E1133B3C986916F1941DA8D423973D -d redirect_uri=https%3A%2F%2Flogin.salesforce.com%2Fservices%2Foauth2%2Fcallback -d grant_type=authorization_code https://login.salesforce.com/services/oauth2/token 
{
    "access_token":"11E2038J02MAaT!AQcAQKDYLmMtLlWgufDra.5oXC.u1ZFKXwqSu2pXYlnyvBsjcgbEYGF5kXN.DrHMwLItYeNE5sBWGwbL1XvJpJHSvORDsVfw","signature":"zhobYu07bjq5JFPpnbAZt8XBJrQjQ2xYrsH09BlIAzI=","scope":"full",
    "id_token":"eyJraWQiOiIyMjYiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdF9oYXNoIjoiX2ROU2tpNzhlNEU5c1o2NjkzcGY4dyIsInN1YiI6Imh0dHBzOi8vbA9naW4uc2FsZXNmb3JjZS5jb20vaWQvMDBEMnYwMDAwMDJMTnNsRUFHLzAwNTJ2MDAwMDBmYW5nUEFBUSIsImF1ZCI6IjNNVkc5RzlwekNVU2t6WnMxR24zMFFFNVVHVjd3TTRDc0RXaDR1Zl9nQ0JIYXoxRFA5MEE0VTUwLjBhZkhQU0hvS1AwU0pIeTdya3habDNQ7HVOcVgiLCJpc3MiOiJpdHRwczovL2xvZ2luLnFhbGVzZm9yY2UuY29tIiwiAXhwIjoxNTpk3OTk2NDkxLCJpYXQiOjE1OTc5OTYzNzF9.hzMXtzhPp9MnbJ6nRJR9Lx7OpjzdD-HMdKSpdhqepELZ0nUGqzeGKEejYUnVwwF-0iltQSV11GPU2wxKcMCgph69N0guxuKtVIMj68GFRDFj_Ph1M4GsUa2u8L4o8a6sUxTQiq88rO8-ctBjkcaBLQ8Nzcpbs9HLiBq3hwmPK4T5FvfFUJut5AcRzImXJYfNZ74DHbprK2q6RYmowbWQdSDUJhw6xTT5c_a5bKEXi8H4uX0IeLIxxTsjYIxwWN3FeYPxM15u5IA9l3F8mYltVEjeD3548BmaXUpnHzWS1v1U5HU50uIeiiiRbe0lhjSs-9kUVXxrrbT23mKHFAKwgDX7bWK-1uRCkab-BlXzH3ENiTTM7TkCky5HHKJr4jLkoXgMI8egL9bkCaOTrr2C3gZHpXhQzq6QV-02r4bZx3xH5kWFxMHzcubeAnJSIC2YnJq7PvWjd5ut5wAqO57it5ZDAVz_8yAQQJe7ZLQ4DlVExcGeTJgiAllBHiojL6ZG0YZt9eRgm7BSa4GQsImOs6ZcA3MZ-NrfmyZfF-iO7HSwi0ty__vTV0YCuV6OaWtN7Y5nLxsTErjEDBnDtwNCcyMaUo0yn5FXE6_rBavFEFltBjfCbRVFR4y9iRe_G6Zwtyk6A3YKJGD7xSLSgNDEN9H787vm57FjbqJouIVTT4Y",
    "instance_url":"https://crq561.salesforce.com",
    "id":"https://login.salesforce.com/id/11E2038J02MAaTEAG/11E2038J02MfangRBAZ",
    "token_type":"Bearer",
    "issued_at":"2297996871526"
}
```

# APIへのアクセス

それでは取得したアクセストークンを使ってAPIにアクセスしてみます。

今回はREST APIでAccount(取引先)オブジェクトの情報を取得します。REST APIについては[Salesforceのリファレンス](https://developer.salesforce.com/docs/atlas.ja-jp.api_rest.meta/api_rest/resources_list.htm)を参考にしてください。

APIへアクセスするにはリクエストヘッダに"Authorization: Bearer <アクセストークン>"を設定します。curlでアクセスする際には-Hオプションを指定してヘッダを設定してください。<アクセストークン>には先ほど取得したアクセストークンを設定します。

```console
> curl -X GET "https://crq561.salesforce.com/services/data/v47.0/sobjects/Account" -H "Authorization: Bearer <アクセストークン>
```

実際にこのAPIにアクセスした結果を示します。先ほど生成したアクセストークンを利用し、指定したオブジェクトの情報が取得できました。

```console
> curl -X GET "https://crq561.salesforce.com/services/data/v47.0/sobjects/Account" -H "Authorization: Bearer 11E2038J02MAaT!AQcAQKDYLmMtLlWgufDra.5oXC.u1ZFKXwqSu2pXYlnyvBsjcgbEYGF5kXN.DrHMwLItYeNE5sBWGwbL1XvJpJHSvORDsVfw" -H "Content-Type: application/json"
{
    "objectDescribe":{
        "activateable":false,
        "createable":true,
        "custom":false,
        "customSetting":false,
        "deletable":true,
        "deprecatedAndHidden":false,
        "feedEnabled":true,
        "hasSubtypes":false,
        "isSubtype":false,
        "keyPrefix":"001",
        "label":"取引先",
        "labelPlural":"取引先",
        "layoutable":true,
        "mergeable":true,
        "mruEnabled":true,
        "name":"Account",
        "queryable":true,
        "replicateable":true,
        "retrieveable":true,
        "searchable":true,
        "triggerable":true,
        "undeletable":true,
        "updateable":true,
        "urls":{
            "compactLayouts":"/services/data/v47.0/sobjects/Account/describe/compactLayouts",
            "rowTemplate":"/services/data/v47.0/sobjects/Account/{ID}",
            "approvalLayouts":"/services/data/v47.0/sobjects/Account/describe/approvalLayouts",
            "defaultValues":"/services/data/v47.0/sobjects/Account/defaultValues?recordTypeId&fields",
            "listviews":"/services/data/v47.0/sobjects/Account/listviews",
            "describe":"/services/data/v47.0/sobjects/Account/describe",
            "quickActions":"/services/data/v47.0/sobjects/Account/quickActions",
            "layouts":"/services/data/v47.0/sobjects/Account/describe/layouts",
            "sobject":"/services/data/v47.0/sobjects/Account"
        }
    },
    "recentItems":[]
}
```