Beberapa update yang dijelaskan di sini dijelaskan dalam sesi Google I/O, Login yang Aman dan Lancar: Menjaga Engagement Pengguna:
Chrome 57
Chrome 57 memperkenalkan perubahan penting ini pada Credential Management API.
Kredensial dapat dibagikan dari subdomain berbeda
Chrome kini dapat mengambil kredensial yang disimpan di subdomain berbeda menggunakan
Credential Management API.
Misalnya, jika sandi disimpan di login.example.com
,
skrip pada www.example.com
dapat menampilkannya sebagai salah satu item akun pada dialog pemilih akun.
Anda harus menyimpan sandi secara eksplisit menggunakan navigator.credentials.store()
,
sehingga saat pengguna memilih kredensial dengan mengetuk dialog,
sandi akan diteruskan dan disalin ke asal saat ini.
Setelah disimpan, sandi akan tersedia sebagai kredensial
di www.example.com
asal yang sama persis dan seterusnya.
Dalam screenshot berikut, informasi kredensial yang disimpan di login.aliexpress.com
terlihat oleh m.aliexpress.com
dan dapat dipilih pengguna:
Chrome 60
Chrome 60 memperkenalkan beberapa perubahan penting pada Credential Management API:
Karena fungsi
fetch()
kustom tidak lagi diperlukan untuk mengambil sandi, fungsi ini tidak akan digunakan lagi dalam waktu dekat.navigator.credentials.get()
sekarang menerima enummediation
, bukan flag booleanunmediated
.Nama
requireUserMediation()
diganti menjadipreventSilentAccess()
.Metode baru
navigator.credentials.create()
membuat objek kredensial secara asinkron.
Deteksi fitur memerlukan perhatian
Untuk melihat apakah Credential Management API untuk mengakses kredensial berbasis sandi dan
gabungan tersedia, periksa apakah window.PasswordCredential
atau
window.FederatedCredential
tersedia.
if (window.PasswordCredential || window.FederatedCredential) {
// The Credential Management API is available
}
Objek PasswordCredential
kini menyertakan sandi
Credential Management API menggunakan pendekatan konservatif untuk menangani sandi.
API ini menyembunyikan sandi dari JavaScript, sehingga developer harus mengirim objek PasswordCredential
langsung ke server mereka untuk divalidasi melalui ekstensi ke fetch()
API.
Namun, pendekatan ini memperkenalkan sejumlah batasan. Kami menerima masukan bahwa developer tidak dapat menggunakan API karena:
Mereka harus mengirimkan sandi sebagai bagian dari objek JSON.
Mereka harus mengirim nilai {i> hash <i}dari {i>password<i} itu ke server mereka.
Setelah melakukan analisis keamanan dan menyadari bahwa menyembunyikan sandi dari JavaScript tidak mencegah semua vektor serangan seefektif yang kami harapkan, kami memutuskan untuk melakukan perubahan.
Credential Management API kini menyertakan sandi mentah dalam objek kredensial yang ditampilkan sehingga Anda dapat mengaksesnya sebagai teks biasa. Anda dapat menggunakan metode yang sudah ada untuk mengirimkan informasi kredensial ke server:
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);
});
Pengambilan kustom tidak akan digunakan lagi dalam waktu dekat
Untuk menentukan apakah Anda menggunakan fungsi fetch()
kustom,
periksa apakah fungsi tersebut menggunakan objek PasswordCredential
atau objek FederatedCredential
sebagai nilai properti credentials
, misalnya:
fetch('/signin', {
method: 'POST',
credentials: c
})
Penggunaan fungsi fetch()
reguler seperti yang ditunjukkan dalam contoh kode sebelumnya, atau penggunaan XMLHttpRequest
direkomendasikan.
navigator.credentials.get()
kini menerima mediasi enum
Hingga Chrome 60, navigator.credentials.get()
menerima properti unmediated
opsional dengan flag boolean. Contoh:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
unmediated: true
}).then(c => {
// Sign-in
});
Menyetel unmediated: true
akan mencegah browser menampilkan pemilih akun
saat meneruskan kredensial.
Tanda tersebut kini diperluas sebagai mediasi. Mediasi pengguna dapat terjadi jika:
Pengguna harus memilih akun untuk login.
Pengguna ingin login secara eksplisit setelah panggilan
navigator.credentials.requireUseMediation()
.
Pilih salah satu opsi berikut untuk nilai mediation
:
Nilai mediation |
Dibandingkan dengan flag boolean | Perilaku | |
---|---|---|---|
silent |
Sama dengan unmediated: true |
Kredensial lulus tanpa menampilkan pemilih akun. | |
optional |
Sama dengan unmediated: false |
Menampilkan pemilih akun jika
preventSilentAccess() dipanggil sebelumnya. |
|
required |
Opsi baru | Selalu tampilkan pemilih akun. Berguna jika Anda ingin mengizinkan pengguna beralih akun menggunakan dialog pemilih akun native. |
Dalam contoh ini,
kredensial diteruskan tanpa menampilkan pemilih akun,
yang setara dengan tanda sebelumnya, unmediated: true
:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
mediation: 'silent'
}).then(c => {
// Sign-in
});
Mengganti nama requireUserMediation()
menjadi preventSilentAccess()
Agar selaras dengan properti mediation
baru yang ditawarkan dalam panggilan get()
,
metode navigator.credentials.requireUserMediation()
telah diganti namanya menjadi
navigator.credentials.preventSilentAccess()
.
Metode yang diganti namanya mencegah penerusan kredensial tanpa menampilkan pemilih akun (terkadang dipanggil tanpa mediasi pengguna). Hal ini berguna saat pengguna logout dari situs atau membatalkan pendaftaran dari situs dan tidak ingin login kembali secara otomatis pada kunjungan berikutnya.
signoutUser();
if (navigator.credentials) {
navigator.credentials.preventSilentAccess();
}
Membuat objek kredensial secara asinkron dengan metode baru navigator.credentials.create()
Kini Anda memiliki opsi untuk membuat objek kredensial secara asinkron
dengan metode baru, navigator.credentials.create()
.
Baca terus untuk mengetahui perbandingan antara pendekatan sinkronisasi dan asinkron.
Membuat objek PasswordCredential
Pendekatan sinkronisasi
let c = new PasswordCredential(form);
Pendekatan asinkron (baru)
let c = await navigator.credentials.create({
password: form
});
atau:
let c = await navigator.credentials.create({
password: {
id: id,
password: password
}
});
Membuat objek FederatedCredential
Pendekatan sinkronisasi
let c = new FederatedCredential({
id: 'agektmr',
name: 'Eiji Kitamura',
provider: 'https://accounts.google.com',
iconURL: 'https://*****'
});
Pendekatan asinkron (baru)
let c = await navigator.credentials.create({
federated: {
id: 'agektmr',
name: 'Eiji Kitamura',
provider: 'https://accounts.google.com',
iconURL: 'https://*****'
}
});
Panduan migrasi
Sudah memiliki implementasi Credential Management API? Kami memiliki dokumen panduan migrasi yang dapat Anda ikuti untuk melakukan upgrade ke versi baru.