單頁面應用程式

使用 IBM Cloud® App ID,您可以快速地將授權及鑑別新增至單頁面應用程式 (SPA)。 SPA 完全在瀏覽器中執行,沒有由您管理的後端,也無需在使用應用程式期間重新載入頁面。 與 SPA 搭配使用的部分一般架構是 AngularReact

您的應用程式是否有由您控制的後端? 如果有, SPA 流程不適合您。 請嘗試使用 Web 應用程式流程

瞭解流程

雖然這是目前 SPA 的業界標準,但 OAuth 工作小組基於多項安全考量,已不再建議使用隱含式流程。 根據他們的建議,App ID 配置為使用 PKCE 的授權碼流程

SPA授權流程
單頁應用的授權流程

  1. 使用者試圖登入到單頁面應用程式。
  2. App ID SDK 為授權要求建立代碼驗證器,這是代碼盤查的明文版本。 用戶端在傳送授權要求時,會一起傳送代碼盤查以及用於對盤查進行編碼的盤查方法。
  3. App ID 將在新視窗中啟動鑑別流程。
  4. 使用者會選擇身分提供者以鑑別及完成登入處理程序。
  5. 應用程式上的 App ID SDK 收到授權碼。
  6. 然後,SDK 向 App ID 記號端點發出 XHR 要求並一起發送授權碼和代碼驗證器,以取得存取記號和身分記號。

您是否在將 SSO 用於 Cloud Directory? 您可以使用 App ID 客戶端 SDK 自動取得一對新的權杖,而不需要使用者明確登入。 如需相關資訊,請參閱無聲自動登入

為什麼要使用授權碼 + PKCE?

單頁面應用程式受自身本質所限,無法安全地儲存密碼。 「授權 + PKCE」流程是 OAuth 2.0 授權碼流程的一種變體,使用一次性代碼驗證器和盤查取代密碼,解決了此問題。 驗證器和盤查可確保呼叫授權和記號端點的實體相同。 此程序表示攻擊者在不知道程式碼驗證器的情況下,也無法向授權伺服器要求記號。

雖然 Implicit flow 是目前的業界標準,但仍可發現幾個安全漏洞。 例如,隱含流程使用重新導向 URI 來取得記號,而「授權 + PKCE」流程使用 XHR 要求規避了這種作法。 由於存在安全缺陷,因此不再建議使用隱式流程,或不再將其視為安全流程,具體原因如下:

  • Implicit flow 會將 tokens 傳回 URL- 作為查詢參數或散列片段。 這種一來,就可以攔截並存取記號。 記號可能會儲存在使用者的瀏覽器歷程或日誌中。 歷程或日誌可能儲存在雲端服務中並傳送到多個裝置,這也增加了風險。

  • 隱含流量容易受到 重定向 URI 攻擊,這表示攻擊者可能會用他們選擇的目的地取代已核准的重定向 URI。 如果有重新導向 URI 攻擊,使用者將遵循已變更的鏈結來授權其用戶端。 授權後,使用者會被重新導向到攻擊者 URI,這將授予攻擊者存取權來存取使用者的合法記號。

相關的重要問題很多,上面僅舉幾例予以說明。 如需詳細資訊,請參閱 OAuth 2.0 安全性最佳現行作法

開始之前

開始之前,請確保已滿足下列必要條件。

  • App ID 服務的實例。
  • 您在 App ID 服務儀表板中設定的 重新導向 URI
  • 單頁面應用程式。 如果沒有單頁面應用程式,但希望試用該流程,請嘗試從 App ID 儀表板的「概觀」頁面中下載範例應用程式。

使用 GUI 建立應用程式認證

認證用於將應用程式連接至 App ID。 若要建立認證,請向 App ID 登錄應用程式。

SPA 憑證中不會傳回任何用戶端秘密。 不需要授權 + PKCE 流程中的密鑰。 您無法在 SPA 流程中使用一般的 Web 應用程式認證。

  1. 在要在其中工作的地區中登入到 IBM Cloud 儀表板。
  2. 導覽至應用程式標籤,然後按一下新增應用程式
  3. 為應用程式提供名稱。
  4. 類型下拉清單,選取單頁面應用程式
  5. 按一下儲存
  6. 在表格中,按一下檢視認證以檢視下列配置中所需的資訊。

使用 API 建立應用程式認證

認證用於將應用程式連接至 App ID。 若要建立認證,請向 App ID 登錄應用程式。

SPA 憑證中不會傳回任何用戶端秘密。 不需要授權 + PKCE 流程中的密鑰。 您無法在 SPA 流程中使用一般的 Web 應用程式認證。

  1. /management/v4//applications 端點。

    curl -X POST \
    https://us-south.appid.cloud.ibm.com/management/v4/<tenantID>/applications/ \
    -H 'accept: application/json' \
    -H 'Authorization: Bearer <IAMToken>' \
    -H 'Content-Type: application/json' \
    -d '{"name": "MySampleSPA", "type": "singlepageapp"}'
    

    回應範例:

    {
       "clientId": "<clientID>",
       "tenantId": "<tenantID>",
       "name": "MySampleSPA",
       "oAuthServerUrl": "https://us-south.appid.cloud.ibm.com/oauth/v4/<tenantID>",
       "type": "singlepageapp"
    }
    

配置 JavaScript SDK

若要在應用程式中安裝 SDK,請使用下列步驟作為手冊。

  1. 使用命令提示字元切換到包含應用程式的目錄。

  2. 使用 NPM 或鏈結主要 HTML 檔案中的 CDN,來安裝 App ID 服務。

    • 若要使用 NPM,請執行下列指令。

      npm install ibmcloud-appid-js
      
    • 若要新增 CDN,請將下列鏈結新增至主要 HTML 檔案。

      <script src="https://cdn.appid.cloud.ibm.com/appid-0.3.0.min.js"></script>
      
  3. 將用戶端 ID 和探索端點新增至應用程式以起始設定 SDK。

    const appID = new AppID();
    await appID.init({
       clientId: '<spaClientID>',
       discoveryEndpoint: '<wellKnownEndpoint>'
    });
    
  4. 在應用程式碼中,配置「登入」按鈕後,新增對 signin 的呼叫。 隨即會開啟一個蹦現視窗,其中提示使用者輸入其認證。 成功鑑別後,該畫面會關閉,此時使用者已經過鑑別。

    const tokens = await appID.signin();
    

配置無聲自動登入

啟用適用於 Cloud Directory 的 SSO 後,如果使用無聲自動登入,則可以自動取得使用者的新記號,使用者便不必重新鑑別。 若要啟用無聲自動登入,請使用下列步驟作為指引。

SPA 流程中不會傳回重新整理記號。

  1. 在 App ID 儀表板中,導覽至 Cloud Directory > 單一登入

  2. 啟用單一登入切換為已啟用

  3. 按一下儲存

  4. 將下列程式碼新增至應用程式。 請務必將應用程式配置為在無聲自動登入失敗時顯示「登入」按鈕。

    const tokens = await appID.silentSignin();
    if (!tokens) {
       document.getElementById('login').addEventListener('click', async () => {
       const tokens = await appID.signin();
       });
    }