Calvert's murmur

透過 OAuth 2.0 JWT 整合 Salesforce API 到你的伺服器

2022-12-16

約 3807 字 / 需 21 分鐘閱讀

有時你會想要授權伺服器來存取資料,而不需在每次伺服器交換資訊時透過互動方式登入。

本文將帶你了解如何整合 Salesforce API 到你的伺服器。我們將使用適用於伺服器對伺服器整合的 OAuth 2.0 JWT 承載者流程來達成此需求。此授權流程使用憑證來簽署 JWT,設定完成後你的伺服器不需要與使用者互動即可呼叫 Salesforce 的 API。但,此流程需要預先授權連線應用程式。

註:在 Salesforce 中,你的自訂應用程式稱為「連線應用程式(Connected App)」。

此教學會涵蓋以下步驟:

  1. 建立 X.509 憑證來識別你的連線應用程式。

  2. 在 Salesforce 建立連線應用程式。

  3. 預先授權「允許的使用者」存取連線應用程式。

  4. 更新使用者設定檔,並指派連線應用程式。

  5. 建立並簽署 JWT。

  6. 使用 JWT 對 Salesforce 發出 HTTP POST 請求要求存取權杖。

  7. Salesforce 將授與存取權杖並回應 HTTP 請求。

建立 X.509 憑證

使用 OpenSSL 為連線應用程式建立 X.509 證書和私鑰。執行以下指令來建立密鑰和證書檔案。

建立私鑰

openssl genrsa -out private.key 4096

建立 X.509 證書

openssl req -new -x509 -key private.key -out cert.pem -days 365

建立連線應用程式

  1. 使用你的管理員帳號登入 Salesforce。

  2. 點選右上方齒輪進入目前的 App 設定頁面。

  3. 在快速搜尋框內輸入「app manager」並點選 App Manager。

  4. 點選 New Connected App。

  5. 輸入欄位資訊如下:

    1. Connected App Name:例如 Demo App

    2. API Name:應該會自動填入如 Demo_App 或類似名稱。

    3. Contact Email:輸入你的聯絡信箱。

    4. 勾選「Enable OAuth Settings」。

    5. Callback URL:例如 http://localhost/callback(本欄位在此範例不會用到,但為 Salesforce 必填欄位)。

    6. 勾選「Use digital signatures」,並點選 Browse 選擇前一個步驟所建立的 cert.pem

    7. 「Selected OAuth Scopes」的部分加入你想要的功能,此處我們選擇 Manage user data via APIs (api)Perform requests at any time (refresh_token, offline_access)

  6. 點選 Save。

  7. 點選 Continue。

  8. 點選 Manage Consumer Details 並在新開啟的頁面將 Consumer Key 記下來,稍後的步驟會用到它。

預先授權「允許的使用者」存取連線應用程式

  1. 在快速搜尋框內輸入「manage connected apps」並點選 Manage Connected Apps。

  2. 對 Demo App 點選 Edit。

  3. 「Permitted Users」的地方選擇「Admin approved users are pre-authorized」。

  4. 點選 Save。

更新使用者設定檔

  1. 在快速搜尋框內輸入「profiles」並點選 Profiles。

  2. 根據你的使用者選擇對應的設定檔,此處我們選擇「System Administrator」。

  3. 點選 Assigned Connected Apps。

  4. 點選 Edit。

  5. 選擇並加入 Demo App 後點選 Save。

建立並簽署 JWT

Salesforce 需要使用 RSA SHA256 來簽署 JWT,連線應用程式會使用建立時所上傳的憑證來確認簽章。

有許多程式語言都有函式庫讓你可以更輕鬆地在程式中使用 JWT。不過,在本篇文章中,我們會使用線上工具來設定我們的 JWT。

現在,我們先來準備設定 JWT 所需的參數:

參數 描述
iss 連線應用程式的 Consumer Key。
aud https://login.salesforce.comhttps://test.salesforce.com
sub Salesforce 使用者名稱,通常是 Email 格式。
exp 有效期限,表示方式為從 UTC 1970-01-01T00:00:00Z 起到現在的總秒數。

你可以在 Linux 或 macOS 使用以下指令來產生有效期限:

# 印出 180 秒 後的時間
echo "$(date +%s) + 180" | bc

開始來建立 JWT 吧

  1. 使用瀏覽器開啟新分頁到 https://jwt.io

  2. 往下捲到 Debugger 的地方。

  3. Algorithm 的地方選擇 RS256

  4. 確認 Header 的資料是否正確

    {
      "alg": "RS256",
      "typ": "JWT"
    }
  5. 設定 Payload,範例如下:

    {
      "iss": "3MVG9yRD.KdtVEtqTFjp0wXaNDJsKX8KyNQxEk_5Sb3rGBKT31MVrvaPOaf0NdG2f8LBjrxqGJqdeGqVWpWc3",
      "aud": "https://login.salesforce.com",
      "sub": "contact@example.com",
      "exp": "1671198418"
    }
  6. 驗證簽章

    1. 使用文字編輯器開啟 cert.pem 並將內容複製到第一個輸入框內。

    2. 使用文字編輯器開啟 private.key 並將內容複製到第二個輸入框內。

    3. 確認左下角顯示的是「Signature Verified」。如果看到「Invalid Signature」,表示你的證書或私鑰有問題。

    4. 複製左側已編碼的 JWT,稍後的步驟會用到它。

向 Salesforce 要求存取權杖

到此,我們可以對 Salesforce 發出 HTTP POST 請求要求存取權杖,相關參數如下:

參數 描述
grant_type 請填入 urn:ietf:params:oauth:grant-type:jwt-bearer
assertion 請填入前一步驟產生的 JWT。
format (選填)用於指定回傳格式,此參數會覆寫請求的標頭,支援 urlencodedjson(預設值)和 xml 格式。

如果所有設定都正確,你應該會收到像這樣的回應:

{
    "access_token": "00DBU0000001gTR!AQEAOJQJCQJtQYOPa2weo4ke.cCz_6_y9tTpluBrPiFWO3lZ7IS5gfoaXKyXrCeHjUnYnQEQE4kk_ogm64slPRszhQTH9QCt",
    "scope": "api",
    "instance_url": "https://demo.my.salesforce.com",
    "id": "https://login.salesforce.com/id/00DBU0000001gKB1CZ/008A2000000IoDSIB0",
    "token_type": "Bearer"
}