登入的使用者

Meggin Kearney
Meggin Kearney

如要讓使用者登入,請從瀏覽器的密碼管理工具擷取憑證,然後使用這些憑證自動登入使用者。如果使用者有多個帳戶,請讓他們透過帳戶選擇器輕鬆選取帳戶。

自動登入功能可在網站的任何位置啟用,不只頂層頁面,其他分葉頁面也適用。當使用者透過搜尋引擎造訪網站中的各個網頁時,這項功能就會派上用場。

如要啟用自動登入功能,請按照下列步驟操作:

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

取得憑證資訊

瀏覽器支援

  • Chrome:51。
  • Edge:18。
  • Firefox:60。
  • Safari: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();
     
}

承諾解析後,請檢查是否已收到憑證物件。如果沒有,表示無法自動登入。自動登入程序會在靜默模式下關閉。

更新使用者介面

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

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

別忘了顯示驗證錯誤訊息

為避免使用者感到困惑,在取得憑證物件時,使用者應會看到「Signing in」的藍色彈出式訊息:

藍色彈出式通知,顯示使用者正在登入。

重要提示:如果您成功取得憑證物件,但無法驗證使用者,則應顯示錯誤訊息:

        }).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. 更新 UI 或前往個人化頁面

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

根據定義的使用者動作顯示帳戶選擇器,例如使用者輕觸「登入」按鈕時。呼叫 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. 更新 UI 或前往個人化頁面 (與自動登入相同)。

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

當使用者輕觸聯合登入按鈕時,請使用 FederatedCredential 執行特定的 ID 提供者驗證流程。

瀏覽器支援

  • Chrome:51。
  • Edge:79。
  • Firefox:不支援。
  • Safari:不支援。

資料來源

舉例來說,如果供應商是 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 為選用)。如要進一步瞭解這項資訊,請參閱 憑證管理規格

如要儲存聯合帳戶詳細資料,請使用使用者 ID 和提供者 ID 例項化新的 FederatedCredential 物件。然後叫用 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();
}

這樣可確保使用者下次啟用自動登入功能前,系統不會自動登入。如要恢復自動登入功能,使用者可以從帳戶選擇器中選擇要登入的帳戶,有意登入。然後使用者會一直保持登入狀態,直到明確登出為止。

意見回饋