登入的使用者

Meggin Kearney
Meggin Kearney

如要登入使用者,請從瀏覽器的密碼擷取憑證 並利用這類帳戶自動登入使用者。 如果使用者有多個帳戶 讓他們使用帳戶選擇工具,輕觸一下即可選取帳戶。

自動登入

網站的任何位置都可能發生自動登入功能; 包括頂端網頁和其他分葉頁面 當使用者進入您網站上的不同網頁時,這項功能就很實用。 來賺取收益

如何啟用自動登入功能:

  1. 取得憑證資訊。
  2. 驗證使用者。
  3. 更新使用者介面或前往個人化頁面。

取得憑證資訊

瀏覽器支援

  • 51
  • 18
  • 60
  • 13

資料來源

如要取得憑證資訊,請叫用 navigator.credentials.get()。 指定要要求的憑證類型 為其提供 passwordfederated 即可。

一律使用 mediation: 'silent' 自動登入, 方便你在遇到下列情況時輕鬆關閉程序:

  • 未儲存任何憑證。
  • 儲存了多個憑證。
  • 已登出。

取得憑證之前 別忘了檢查使用者是否已登入:

if (window.PasswordCredential || window.FederatedCredential) {
  if (!user.isSignedIn()) {
    navigator.credentials.get({
      password: true,
      federated: {
        providers: ['https://accounts.google.com'],
      },
      mediation: 'silent',
    });
    // ...
  }
}

navigator.credentials.get() 傳回的承諾會解析 其中含有憑證物件或 null 如要判斷是 PasswordCredential 還是 FederatedCredential, 只要查看物件的 .type 屬性即可 格式為 passwordfederated

如果 .typefederated.provider 屬性是代表識別資訊提供者的字串。

驗證使用者

取得憑證後 根據憑證類型執行驗證流程 passwordfederated

    }).then(c => {
     if (c) {
       switch (c.type) {
         case 'password':
           return sendRequest(c);
           break;
         case 'federated':
           return gSignIn(c);
           break;
       }
     } else {
       return Promise.resolve();
     }

問題解決後 檢查您是否已收到憑證物件。 如果不是,表示無法自動登入。 關閉自動登入程序。

更新 UI

如果驗證成功 更新使用者介面,或將使用者導向個人化頁面:

    }).then(profile => {
     if (profile) {
       updateUI(profile);
     }

別忘了顯示驗證錯誤訊息

為避免造成使用者混淆 此時,使用者應該會看到「登入」的藍色浮動式訊息 寫入憑證物件時:

顯示使用者正在登入的藍色浮動式訊息。

重要提示:如果成功取得憑證物件 但無法驗證使用者,此時會顯示下列錯誤訊息:

        }).catch(error => {
          showError('Sign-in Failed');
        });
      }
    }

完整程式碼範例

if (window.PasswordCredential || window.FederatedCredential) {
  if (!user.isSignedIn()) {
    navigator.credentials
      .get({
        password: true,
        federated: {
          providers: ['https://accounts.google.com'],
        },
        mediation: 'silent',
      })
      .then((c) => {
        if (c) {
          switch (c.type) {
            case 'password':
              return sendRequest(c);
              break;
            case 'federated':
              return gSignIn(c);
              break;
          }
        } else {
          return Promise.resolve();
        }
      })
      .then((profile) => {
        if (profile) {
          updateUI(profile);
        }
      })
      .catch((error) => {
        showError('Sign-in Failed');
      });
  }
}

透過帳戶選擇工具登入

如果使用者需要中介服務,或有多個帳戶 使用帳戶選擇工具讓使用者登入 略過一般登入表單,例如:

顯示多個帳戶的 Google 帳戶選擇工具。

透過帳戶選擇工具登入的步驟與 自動登入, 另通來電以顯示帳戶選擇工具 在取得憑證資訊時:

  1. 取得憑證資訊並顯示帳戶選擇工具。
  2. 驗證使用者
  3. 更新使用者介面或繼續前往個人化頁面

取得憑證資訊並顯示帳戶選擇工具

根據已定義的使用者動作顯示帳戶選擇工具。 例如使用者輕觸「登入」按鈕。致電 navigator.credentials.get()、 並新增 mediation: 'optional'mediation: 'required',顯示帳戶選擇工具。

如果 mediationrequired,系統一律會向使用者顯示帳戶選擇工具登入。 這個選項可讓擁有多個帳戶的使用者輕鬆切換不同帳戶。 當 mediationoptional 時, 系統明確顯示帳戶選擇工具,讓使用者在登入後 navigator.credentials.preventSilentAccess()敬上 呼叫。 這通常用於確保不會自動登入 使用者選擇登出或取消註冊後。

顯示 mediation: 'optional' 的範例:

    var signin = document.querySelector('#signin');
    signin.addEventListener('click', e => {
     if (window.PasswordCredential || window.FederatedCredential) {
       navigator.credentials.get({
         password: true,
         federated: {
           providers: [
             'https://accounts.google.com'
           ]
         },
         mediation: 'optional'
       }).then(c => {

使用者選取帳戶後 承諾會用憑證解析 如果使用者取消帳戶選擇工具, 或是未儲存憑證 承諾使用 null 就會解決。 在此情況下,請改回使用登入表單。

別忘了返回登入表單

基於下列任何一種原因,你應該切換回登入表單:

  • 未儲存任何憑證。
  • 使用者已關閉帳戶選擇工具,但未選取帳戶。
  • API 無法使用。
    }).then(profile => {
        if (profile) {
          updateUI(profile);
        } else {
          location.href = '/signin';
        }
    }).catch(error => {
        location.href = '/signin';
    });

完整程式碼範例

var signin = document.querySelector('#signin');
signin.addEventListener('click', (e) => {
  if (window.PasswordCredential || window.FederatedCredential) {
    navigator.credentials
      .get({
        password: true,
        federated: {
          providers: ['https://accounts.google.com'],
        },
        mediation: 'optional',
      })
      .then((c) => {
        if (c) {
          switch (c.type) {
            case 'password':
              return sendRequest(c);
              break;
            case 'federated':
              return gSignIn(c);
              break;
          }
        } else {
          return Promise.resolve();
        }
      })
      .then((profile) => {
        if (profile) {
          updateUI(profile);
        } else {
          location.href = '/signin';
        }
      })
      .catch((error) => {
        location.href = '/signin';
      });
  }
});

聯合登入

有了聯合登入,使用者只要輕觸一下即可登入 不必記住網站的其他登入詳細資料。

如何實作聯合登入:

  1. 使用第三方身分驗證使用者。
  2. 儲存識別資訊。
  3. 更新使用者介面或前往個人化網頁 (與自動登入相同)。

使用第三方身分驗證使用者

當使用者輕觸聯合登入按鈕時, 並透過 FederatedCredential

瀏覽器支援

  • 51
  • 79
  • x
  • x

資料來源

舉例來說,如果供應器是 Google,請使用 Google 登入 JavaScript 程式庫

navigator.credentials
  .get({
    password: true,
    mediation: 'optional',
    federated: {
      providers: ['https://account.google.com'],
    },
  })
  .then(function (cred) {
    if (cred) {
      // Instantiate an auth object
      var auth2 = gapi.auth2.getAuthInstance();

      // Is this user already signed in?
      if (auth2.isSignedIn.get()) {
        var googleUser = auth2.currentUser.get();

        // Same user as in the credential object?
        if (googleUser.getBasicProfile().getEmail() === cred.id) {
          // Continue with the signed-in user.
          return Promise.resolve(googleUser);
        }
      }

      // Otherwise, run a new authentication flow.
      return auth2.signIn({
        login_hint: id || '',
      });
    }
  });

Google 登入會產生 ID 權杖做為驗證的證明。

一般來說,聯合登入是以標準通訊協定為基礎,例如 OpenID ConnectOAuth。 想瞭解如何使用聯合帳戶進行驗證 請參閱各個聯合識別資訊提供者的文件。 以下列舉幾個熱門的例子:

儲存身分資訊

完成驗證後,即可儲存身分識別資訊。 您在這裡儲存的資訊是識別資訊提供者提供的 id 以及代表識別資訊提供者的提供者字串 (nameiconURL 為選用項目)。 如要進一步瞭解這項資訊,請前往 Credential Management 規格

如要儲存聯合帳戶詳細資料,請將新的 FederatedCredential敬上 與使用者 ID 和提供者 ID 建立關聯。 然後叫用 navigator.credentials.store()敬上 儲存識別資訊。

成功建立聯盟後 以同步或非同步方式將 FederatedCredential 執行個體化:

同步方法的範例:

// Create credential object synchronously.
var cred = new FederatedCredential({
  id: id, // id in IdP
  provider: 'https://account.google.com', // A string representing IdP
  name: name, // name in IdP
  iconURL: iconUrl, // Profile image url
});

非同步方法的範例:

// Create credential object asynchronously.
var cred = await navigator.credentials.create({
  federated: {
    id: id,
    provider: 'https://accounts.google.com',
    name: name,
    iconURL: iconUrl,
  },
});

然後儲存憑證物件:

// Store it
navigator.credentials.store(cred).then(function () {
  // continuation
});

登出

輕觸登出按鈕後,將使用者登出。 首先終止工作階段 然後關閉自動登入功能,日後造訪時即可。 (活動終止方式完全由您決定)。

關閉日後造訪時自動登入的功能

致電 navigator.credentials.preventSilentAccess()

signoutUser();
if (navigator.credentials && navigator.credentials.preventSilentAccess) {
  navigator.credentials.preventSilentAccess();
}

這樣可確保使用者下次啟用自動登入功能時,不會自動登入。 如要繼續自動登入,使用者可以選擇刻意登入 從帳戶選擇工具中選擇要登入的帳戶。 如此一來,除非使用者明確登出,否則系統一律會重新登入。

意見回饋