[譯] 使用認證管理 API 簡化登錄

原文連接: http://lea.verou.me/2015/12/my-positive-experience-as-a-woman-in-tech/

為了提供優質的用戶體驗,我們應該幫助用戶在不同網頁進行身份認證。完成認證的用戶可以在不同網頁擁有不同的資料,在多設備之間同步數據,或是在離線情況下處理數據;可以擴展的功能數之不盡。但是創建賬號、記住和輸入密碼對用戶來說非常麻煩,尤其是在手機端,這通常導致用戶在不同網站使用同一份密碼。這在安全性上有很大的風險。

Chrome 51(最新版本)支持了 Credential Management API(證書管理API) 。它遵循了W3C提議的標準,為開發者提供了管理瀏覽器認證的入口,以幫助用戶以更簡單的方式登錄。

認證管理API的設計目標

通過認證管理API, 開發者可以保存和獲取密碼認證信息和聯合認證信息。它提供了一下3個方法:

  • navigator.credentials.get()

  • navigator.credentials.store()

  • navigator.credentials.requireUserMediation()

通過使用這些API,開發者可以完成以下強大的功能:

  • 讓用戶可以通過一次點擊完成登錄

  • 記錄用戶登錄時使用的聯合認證賬號

  • 當session過期時,幫助用戶重新登錄

在Chrome的實現中,認證信息會被保存在Chrome的密碼管理器中。用戶登陸后,可以在多設備之間同步密碼。同步的密碼也可以被分享給Android應用,只要這些應用集成了 Smart Lock for Passwords for Android , 以提供無縫的跨平臺體驗 .

在網站中集成認證管理API

如何使用認證管理API,取決于你的網站架構是如何設計的。你的網站是一個單頁應用?是一個涉及頁面切換的傳統架構?只能在首頁登錄?還是到處都能登錄?用戶可否在不登錄的情況下瀏覽網頁?登錄操作是否在彈出的窗口中進行?還是說需要操作不同的頁面才能登錄。

我們不可能覆蓋所有的場景,但讓我們先通過一個典型的單頁應用了解一下:

  • 首頁是一個登錄表單。

  • 點擊“登錄”按鈕時,用戶會被導向一個登錄表單。

  • 注冊和登錄表單都提供了id/password認證與聯合認證登錄的選項,例如:通過Google登錄,或通過Facebook登錄。

使用認證管理API,我們可以為網站添加以下功能,例如:

  • 在用戶登錄時,顯示賬號選擇框:當用戶點擊“登錄”時,彈出原生賬號選擇框。

  • 保存認證信息:在用戶成功登錄后,使用瀏覽器的密碼管理器保存認證信息,以便日后使用。

  • 調解自動登錄:一旦用戶退出登錄,在用戶下一次訪問時,停止自動登錄。

你們可以通過 這個例子 體驗一下,它的代碼在 這兒 .

注意:這些API只能在安全網站中使用,例如HTTPS網站、locolhost

登錄時顯示賬號選擇框

在用戶點擊了“登錄”按鈕,并跳到登錄表單之前,你可以通過 navigator.credentials.get() 方法獲得認證信息。Chrome會彈出一個賬號選擇框,供用戶選擇。

[譯] 使用認證管理 API 簡化登錄 彈出了一個賬號選擇框,用戶可選擇一個賬號進行登錄。

獲取密碼認證對象

如果想支持通過密碼認證登錄,請使用 password: true

navigator.credentials.get({     password: true, // 設置為true,以獲取密碼認證對象 }).then(function(cred) {     // 繼續   ...

使用密碼認證登錄

當用戶選擇了一個賬號時,resolve函數會收到一個密碼認證對象,你可以通過 fetch() 方法將信息發送到服務器

// 延續上一個例子 }).then(function(cred) {     if (cred) {       if (cred.type == 'password') {         // 構建FormData對象       var form = new FormData();        // 添加CSRF令牌       var csrf_token = document.querySelector('csrf_token').value;         form.append('csrf_token', csrf_token);        // 你可以將額外信息添加到`.additionalData`       cred.additionalData = form;        // 將認證對象作為`credentials`通過`POST`請求發送       // id, 密碼和額外信息會被加密,并作為HTTP主體被發送給接口       fetch(url, {           // 請保證url是HTTPS鏈接         method: 'POST',      // 使用POST方法         credentials: cred    // 添加密碼認證對象       }).then(function() {           // 繼續         });       } else if (cred.type == 'federated') {         // 繼續

使用聯合認證登錄

如果想為用戶展示聯合登錄賬號,請在調用 get() 方法時,通過 federated 選項定義一個包含賬號提供者id的數組。

[譯] 使用認證管理 API 簡化登錄 密碼管理器保存了多個賬號

navigator.credentials.get({     password: true, // 設置為true,以獲得密碼認證對象   federated: {       providers: [  // 定義一個由聯合賬號供應者id組成的數組       '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`屬性包含了聯合賬號供應者的id       switch (cred.provider) {           case 'https://accounts.google.com':             // 使用Google Sign-In進行聯合登錄           var auth2 = gapi.auth2.getAuthInstance();            // 使用Google Sign-In庫時,可以通過login_hint指定一個賬號           return auth2.signIn({               login_hint: cred.id || ''             }).then(function(profile) {               // 繼續             });             break;          case 'https://www.facebook.com':             // 使用Facebook Login進行聯合登錄           // 繼續           break;          default:             // 顯示表單           break;         }       }     // 如果cred是undefined   } else {         // 顯示表單

[譯] 使用認證管理 API 簡化登錄

保存認證對象

當用戶通過表單登錄你的網站時,你可以使用 navigator.credentials.store() 來保存認證信息。瀏覽器會詢問用戶是否希望保存。你可以根據認證的類型,決定使用 new PasswordCredential() 還是 new FederatedCredential() 來創建認證對象并保存。

[譯] 使用認證管理 API 簡化登錄 Chrome詢問用戶是否希望保存認證信息(或是作為聯合賬號)

通過表單元素創建和保存密碼認證對象

以下代碼通過屬性 autocomplete ,自動將表單元素  映射 為 PasswordCredential 對象的參數

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);   // 保存認證對象 navigator.credentials.store(cred)   .then(function() {     // 繼續 });

創建和保存聯合認證對象

// 在聯合認證后,通過你獲得的信息創建一個FederatedCredential對象 var cred = new FederatedCredential({     id: id,                                  // 用戶id   name: name,                              // 可選的用戶名   provider: 'https://accounts.google.com',  // 聯合賬號提供者的id   iconURL: iconUrl                         // 可選的用戶頭像地址 });   // 保存認證對象 navigator.credentials.store(cred)   .then(function() {     // 繼續 });

[譯] 使用認證管理 API 簡化登錄

使用戶自動重新登錄

當用戶再次訪問網站時,session有可能已經失效了。我們不必麻煩用戶每次回訪的時候重新輸入密碼。可以幫助他們自動重新登錄。

[譯] 使用認證管理 API 簡化登錄 當用戶自動登錄時,會彈出一個通知

獲取一個認證對象

navigator.credentials.get({     password: true,   federated: {     providers: [       'https://accounts.google.com',         'https://www.facebook.com'       ]     },     unmediated: true // 設置為true,以支持用戶自動登錄   }).then(function(cred) {     if (cred) {       // 可以自動登錄     ...     } else {       // 不可以自動登錄     ...   }   });

這段代碼與你在前面的“顯示賬號選擇框”部分的代碼相似。唯一的區別是這兒設置了 unmediated: true

這會使函數馬上 resolve ,并返回一個認證對象,幫助用戶自動登錄。自動登錄有以下條件:

  • 瀏覽器已顯式地告知用戶正在進行自動登錄

  • 用戶曾經通過認證管理API登陸了網站

  • 用戶在瀏覽你的網站時只保存了一個認證對象

  • 用戶在上一次訪問時沒有主動退出登錄

如果任意條件不符合,這個函數便會被 reject

[譯] 使用認證管理 API 簡化登錄

調解(Mediate)自動登錄

當用戶退出登錄時, 應該由你來確保用戶下次回訪時不會自動登錄 。認證管理API提供了一種叫作 mediation(調解) 的機制來確保這一點。你可以通過調用 navigator.credentials.requireUserMediation() 來開啟調解模式。只要用戶在這個網站中的調解狀態為開啟,那么如果你在 navigator.credentials.get() 方法中選擇了 unmediate:true ,這個函數會在 resolve 時,傳入 undefined

調解自動登錄

navigator.credentials.requireUserMediation();

[譯] 使用認證管理 API 簡化登錄

FAQ

在網頁中,Javascript是否有可能獲得原始密碼?

不能。密碼只能作為 PasswordCredential 對象中的一部分,對外是不可訪問的。

No. You can only obtain passwords as a part of  PasswordCredential and it’s not exposable by any means.

Is it possible to store 3 set of digits for an id using Credential Management API? 我們可以通過認證管理API為一個id保存三組數字嗎?

目前還不行。我們非常感謝你 對標準的反饋

我可以在iframe中使用認證管理API嗎?

這個API只能在最高級的上下文中使用。如果在iframe中調用 .get().store() 方法,這些方法會馬上 resolve ,并且不會產生任何效果。

我可以在我的密碼管理Chrome擴展中集成認證管理API嗎?

你可以重寫 navigator.credentials ,并將它指向你的Chrome擴展,由擴展來 get()store() 認證對象。

作者

[譯] 使用認證管理 API 簡化登錄

原文  http://hao.jser.com/archive/10361/

本站部分文章源于互聯網,本著傳播知識、有益學習和研究的目的進行的轉載,為網友免費提供。如有著作權人或出版方提出異議,本站將立即刪除。如果您對文章轉載有任何疑問請告之我們,以便我們及時糾正。

PS:推薦一個微信公眾號: askHarries 或者qq群:474807195,里面會分享一些資深架構師錄制的視頻錄像:有Spring,MyBatis,Netty源碼分析,高并發、高性能、分布式、微服務架構的原理,JVM性能優化這些成為架構師必備的知識體系。還能領取免費的學習資源,目前受益良多

轉載請注明原文出處:Harries Blog? » [譯] 使用認證管理 API 簡化登錄

贊 (0)
分享到:更多 ()

評論 0

  • 昵稱 (必填)
  • 郵箱 (必填)
  • 網址
2013平特肖公式