此處說明的某些更新已在 Google I/O 大會講座中說明安全流暢的登入機制:吸引使用者互動:
Chrome 57
Chrome 57 為 Credential Management API 推出了這項重要變更。
可透過不同的子網域共用憑證
Chrome 現在可以使用 Credential Management API 擷取儲存在其他子網域的憑證。舉例來說,如果密碼儲存在 login.example.com
中,www.example.com
上的指令碼可將該密碼顯示為帳戶選擇工具對話方塊中的一個帳戶項目。
您必須使用 navigator.credentials.store()
明確儲存密碼,這樣當使用者輕觸對話方塊選擇憑證時,系統就會將密碼傳遞並複製到目前的來源。
儲存儲存後,這組密碼就能做為相同來源 www.example.com
日後使用的憑證使用。
在以下螢幕截圖中,m.aliexpress.com
可以查看儲存在 login.aliexpress.com
中的憑證資訊,且使用者可以選擇:
Chrome 60
Chrome 60 為 Credential Management API 推出了幾項重要異動:
由於擷取密碼時不再需要自訂
fetch()
函式,因此將於近期淘汰。navigator.credentials.get()
現在接受列舉mediation
,而非布林值標記unmediated
。新方法
navigator.credentials.create()
會以非同步方式建立憑證物件。
功能偵測功能需要處理
如要查看 Credential Management API 是否可用以存取密碼式和聯合憑證,請檢查 window.PasswordCredential
或 window.FederatedCredential
是否可用。
if (window.PasswordCredential || window.FederatedCredential) {
// The Credential Management API is available
}
PasswordCredential
物件現在包含密碼
Credential Management API 會以保守的方式處理密碼。應用程式會隱藏 JavaScript 的密碼,要求開發人員將 PasswordCredential
物件直接傳送至其伺服器,以便透過擴充功能傳送至 fetch()
API 進行驗證。
但此方法引發了幾項限制。我們收到開發人員的意見回饋,指出 API 無法使用這個 API,原因如下:
他們必須傳送 JSON 物件中的密碼。
他們必須將密碼的雜湊值傳送到自己的伺服器。
執行安全性分析,並確認隱藏 JavaScript 密碼後,並不像我們預期的有效攻擊媒介,我們還是決定做出改變。
Credential Management API 現在可在傳回的憑證物件中加入原始密碼,方便您以純文字格式存取。您可以使用現有方法將憑證資訊傳送至伺服器:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
mediation: 'silent'
}).then(passwordCred => {
if (passwordCred) {
let form = new FormData();
form.append('email', passwordCred.id);
form.append('password', passwordCred.password);
form.append('csrf_token', csrf_token);
return fetch('/signin', {
method: 'POST',
credentials: 'include',
body: form
});
} else {
// Fallback to sign-in form
}
}).then(res => {
if (res.status === 200) {
return res.json();
} else {
throw 'Auth failed';
}
}).then(profile => {
console.log('Auth succeeded', profile);
});
自訂擷取功能即將淘汰
如要判斷您使用的是自訂的 fetch()
函式,請檢查該函式是否使用 PasswordCredential
物件,還是 FederatedCredential
物件做為 credentials
屬性的值,例如:
fetch('/signin', {
method: 'POST',
credentials: c
})
建議使用上述程式碼範例中的一般 fetch()
函式,或是使用 XMLHttpRequest
。
navigator.credentials.get()
現在接受列舉中介服務
在 Chrome 60 之前,navigator.credentials.get()
接受具有布林值標記的選用 unmediated
屬性。例如:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
unmediated: true
}).then(c => {
// Sign-in
});
設定 unmediated: true
可防止瀏覽器在傳送憑證時顯示帳戶選擇工具。
此標記現已擴充為中介服務。符合使用者中介服務的情況如下:
使用者需要選擇用來登入的帳戶。
使用者想要在
navigator.credentials.requireUseMediation()
呼叫後明確登入。
針對 mediation
值選擇下列其中一個選項:
mediation 值 |
與布林值標記相比 | 行為 | |
---|---|---|---|
silent |
等於 unmediated: true |
憑證已通過,但未顯示帳戶選擇工具。 | |
optional |
等於 unmediated: false |
如果先前已呼叫 preventSilentAccess() ,顯示帳戶選擇工具。 |
|
required |
新選項 | 一律顯示帳戶選擇工具。 當您想讓使用者使用原生帳戶選擇工具對話方塊切換帳戶時,這個選單就可以派上用場。 |
在此範例中,系統在傳送憑證時不會顯示帳戶選擇工具 (與前一個標記 unmediated: true
相等),但不會顯示帳戶選擇工具:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
mediation: 'silent'
}).then(c => {
// Sign-in
});
requireUserMediation()
已重新命名為 preventSilentAccess()
為了與 get()
呼叫中提供的新 mediation
屬性順利保持一致,navigator.credentials.requireUserMediation()
方法已重新命名為 navigator.credentials.preventSilentAccess()
。
重新命名的方法可避免在未顯示帳戶選擇工具的情況下傳送憑證 (有時在沒有使用者中介服務的情況下呼叫)。當使用者登出網站或取消註冊網站,且不想在下次造訪時自動重新登入時,這項功能就能派上用場。
signoutUser();
if (navigator.credentials) {
navigator.credentials.preventSilentAccess();
}
使用新方法 navigator.credentials.create()
,以非同步方式建立憑證物件
您現在可以選擇使用新方法 navigator.credentials.create()
,以非同步方式建立憑證物件。請繼續閱讀下文,比較同步和非同步方法的差異。
建立 PasswordCredential
物件
同步處理方法
let c = new PasswordCredential(form);
非同步方法 (新功能)
let c = await navigator.credentials.create({
password: form
});
或是:
let c = await navigator.credentials.create({
password: {
id: id,
password: password
}
});
建立 FederatedCredential
物件
同步處理方法
let c = new FederatedCredential({
id: 'agektmr',
name: 'Eiji Kitamura',
provider: 'https://accounts.google.com',
iconURL: 'https://*****'
});
非同步方法 (新功能)
let c = await navigator.credentials.create({
federated: {
id: 'agektmr',
name: 'Eiji Kitamura',
provider: 'https://accounts.google.com',
iconURL: 'https://*****'
}
});
遷移指南
已經導入 Credential Management API 嗎?您可以參閱這份遷移指南文件,瞭解如何升級至新版本。