使用憑證管理 API 簡化登入流程

為了提供完善的使用者體驗,請務必協助使用者 驗證您的網站通過驗證的使用者可以與你互動 並利用專屬設定檔同步處理各裝置的資料,在不同裝置上同步處理資料或處理資料 離線狀態;繼續保持但必須創作、記住及打字 密碼對使用者來說很麻煩,特別是在行動裝置螢幕上 導致他們在不同網站上重複使用相同密碼。這當然 存在安全風險

最新版本的 Chrome (51) 支援 Credential Management API。這是 標準-追蹤提案,方便開發人員透過程式 中的憑證管理工具,可讓使用者輕鬆登入。

什麼是 Credential Management API?

Credential Management API 可讓開發人員儲存及擷取密碼 憑證和聯合憑證,並提供 3 個功能:

  • navigator.credentials.get()
  • navigator.credentials.store()
  • navigator.credentials.requireUserMediation()

開發人員可以利用這些簡單的 API,享有下列強大功能:

  • 讓使用者只要輕觸一下即可登入。
  • 記住使用者用於登入的聯合帳戶。
  • 工作階段結束時,使用者即可重新登入。

實作 Chrome 時,憑證會儲存在 Chrome 的密碼中 聯絡。如果使用者已登入 Chrome,就能同步處理使用者的密碼 跨裝置使用 YouTube你也可以將這些已同步處理的密碼分享給 Android 應用程式 整合 Android 專用 Smart Lock API 就能享有無縫接軌的跨平台體驗

將 Credential Management API 與您的網站整合

在網站上使用 Credential Management API 的方式可能有所不同 支援多種架構這是單頁應用程式嗎?是舊版嗎? 以及頁面轉換的架構?登入表單是否只出現在頂端 網頁?登入按鈕是否位於任何地方?使用者可以進行有意義的瀏覽 或是不登入帳戶的網站?聯盟可以在彈出式視窗中使用嗎?或是 是否需要在多個網頁上進行互動?

幾乎不可能涵蓋所有的案例,但我們來看看 常見的單頁應用程式

  • 頁面頂端會顯示註冊表單,
  • 輕觸「登入」之後,使用者會前往登入表單。
  • 註冊表單和登入表單都有常見的 ID/密碼選項 憑證和聯盟,例如「使用 Google 登入」 和「Facebook 登入」

只要使用 Credential Management API,您就能新增下列資料 網站功能,例如:

  • 在登入時顯示帳戶選擇工具:顯示原生帳戶選擇工具 UI 使用者輕觸「登入」時。
  • 商店憑證:登入成功後,會提供儲存 將憑證資訊傳送給瀏覽器密碼管理工具,以供日後使用。
  • 允許使用者自動重新登入: 因此 訊息已過期
  • 中介服務自動登入機制:使用者登出後,停用下列帳戶的自動登入功能: 使用者下次造訪的時間

您可以在示範網站透過範例程式碼體驗實作的功能。

在登入時顯示帳戶選擇工具

在使用者輕觸「登入」之間使用者點選按鈕和登入表單時 可以使用 navigator.credentials.get() 以取得憑證資訊Chrome 會顯示帳戶選擇工具使用者介面 讓使用者自行選擇帳戶

帳戶選擇工具使用者介面會彈出,讓使用者選取要登入的帳戶。
帳戶選擇工具使用者介面彈出,供使用者選取要登入的帳戶

取得密碼憑證物件

如要以帳戶選項顯示密碼憑證,請使用 password: true

navigator.credentials.get({
    password: true, // `true` to obtain password credentials
}).then(function(cred) {
    // continuation
    ...

使用密碼憑證登入

使用者選取帳戶後,解析函式會收到 密碼認證。您可以使用 fetch() 將其傳送至伺服器:

    // continued from previous example
}).then(function(cred) {
    if (cred) {
    if (cred.type == 'password') {
        // Construct FormData object
        var form = new FormData();

        // Append CSRF Token
        var csrf_token = document.querySelector('csrf_token').value;
        form.append('csrf_token', csrf_token);

        // You can append additional credential data to `.additionalData`
        cred.additionalData = form;

        // `POST` the credential object as `credentials`.
        // id, password and the additional data will be encoded and
        // sent to the url as the HTTP body.
        fetch(url, {           // Make sure the URL is HTTPS
        method: 'POST',      // Use POST
        credentials: cred    // Add the password credential object
        }).then(function() {
        // continuation
        });
    } else if (cred.type == 'federated') {
        // continuation

使用聯合憑證登入

如要向使用者顯示聯合帳戶,請新增 federated,可採用陣列 識別資訊提供者的 get() 選項。

密碼管理工具中儲存多個帳戶。
密碼管理工具中儲存多個帳戶
navigator.credentials.get({
    password: true, // `true` to obtain password credentials
    federated: {
    providers: [  // Specify an array of IdP strings
        'https://accounts.google.com',
        'https://www.facebook.com'
    ]
    }
}).then(function(cred) {
    // continuation
    ...

您可以檢查憑證物件的 type 屬性,確認該物件是否為 PasswordCredential (type == 'password') 或 FederatedCredential (type == 'federated')。 如果憑證為 FederatedCredential, 您可以使用其中包含的資訊呼叫適當的 API。

    });
} else if (cred.type == 'federated') {
    // `provider` contains the identity provider string
    switch (cred.provider) {
    case 'https://accounts.google.com':
        // Federated login using Google Sign-In
        var auth2 = gapi.auth2.getAuthInstance();

        // In Google Sign-In library, you can specify an account.
        // Attempt to sign in with by using `login_hint`.
        return auth2.signIn({
        login_hint: cred.id || ''
        }).then(function(profile) {
        // continuation
        });
        break;

    case 'https://www.facebook.com':
        // Federated login using Facebook Login
        // continuation
        break;

    default:
        // show form
        break;
    }
}
// if the credential is `undefined`
} else {
// show form
憑證管理流程圖。

儲存憑證

當使用者使用表單登入您的網站時,您可以使用 navigator.credentials.store() 儲存憑證。系統會提示使用者儲存是否儲存。視情況而定 憑證類型,請使用 new PasswordCredential()new FederatedCredential() 建立您要儲存的憑證物件

Chrome 會詢問使用者是否要儲存憑證 (或聯盟提供者),
Chrome 會詢問使用者是否要儲存憑證 (或聯盟提供者)

透過表單元素建立及儲存密碼憑證

以下程式碼會使用 autocomplete 屬性, 地圖 表單元素與 PasswordCredential 的元素 物件參數

HTML html <form id="form" method="post"> <input type="text" name="id" autocomplete="username" /> <input type="password" name="password" autocomplete="current-password" /> <input type="hidden" name="csrf_token" value="******" /> </form>

JavaScript

var form = document.querySelector('\#form');
var cred = new PasswordCredential(form);
// Store it
navigator.credentials.store(cred)
.then(function() {
    // continuation
});

建立及儲存聯合憑證

// After a federation, create a FederatedCredential object using
// information you have obtained
var cred = new FederatedCredential({
    id: id,                                  // The id for the user
    name: name,                              // Optional user name
    provider: 'https://accounts.google.com',  // A string that represents the identity provider
    iconURL: iconUrl                         // Optional user avatar image url
});
// Store it
navigator.credentials.store(cred)
.then(function() {
    // continuation
});
登入流程圖。

允許使用者自動重新登入

使用者離開網站後又再次回訪,很有可能 因此 訊息已過期避免使用者每次都要輸入密碼 應用程式。讓使用者自動重新登入。

使用者自動登入後,系統會彈出通知視窗。
使用者自動登入後,系統會彈出通知視窗。

取得憑證物件

navigator.credentials.get({
    password: true, // Obtain password credentials or not
    federated: {    // Obtain federation credentials or not
    providers: [  // Specify an array of IdP strings
        'https://accounts.google.com',
        'https://www.facebook.com'
    ]
    },
    unmediated: true // `unmediated: true` lets the user automatically sign in
}).then(function(cred) {
    if (cred) {
    // auto sign-in possible
    ...
    } else {
    // auto sign-in not possible
    ...
    }
});

程式碼看起來應該會與「顯示帳戶選擇工具」中 登入時」專區。唯一的差別在於您應將 unmediated: true

這樣可以立即解析函式,並為您提供 自動讓使用者登入以下是幾個條件:

  • 使用者表示同意自動登入功能,歡迎踴躍加入。
  • 使用者先前已透過 Credential Management API 登入網站。
  • 使用者只儲存了一個來源的憑證。
  • 使用者未在上一個工作階段中明確登出。

如果不符合上述任一條件,系統就會拒絕函式。

憑證物件流程圖

中介服務自動登入

使用者登出您的網站時,您有責任確保 系統不會自動將使用者重新登入。為了確保 因此 Credential Management API 提供稱為「中介服務」的機制。 您只要呼叫 navigator.credentials.requireUserMediation()。 只要使用者來源的中介服務狀態已開啟,系統就會使用 帶有 navigator.credentials.get()unmediated: true,該函式將 解析為 undefined

正在中介自動登入

navigator.credentials.requireUserMediation();
自動登入流程圖。

常見問題

網站上的 JavaScript 是否可能擷取原始 密碼? 不可以。您只能取得 PasswordCredential 網域設定的密碼,否則無法取得密碼 就可以透過任何方式暴露在風險中

可以使用憑證來儲存 3 組數字 Management API? 目前還不行。您的規格意見回饋將 非常感謝。

我可以在 iframe 中使用 Credential Management API 嗎? 這個 API 只能用於頂層結構定義。撥打 .get().store() 的電話 則不會立即生效

我可以將密碼管理 Chrome 擴充功能與憑證整合 Management API? 你可以將 navigator.credentials 覆寫並連結至 Chrome 擴充功能,以便 get()store() 憑證。

資源

如要進一步瞭解 Credential Management API,請參閱整合指南