Beberapa update yang dijelaskan di sini dijelaskan dalam sesi Google I/O, Login yang Aman dan Lancar: Menjaga Pengguna Tetap Terlibat:
Chrome 57
Chrome 57 memperkenalkan perubahan penting ini pada Credential Management API.
Kredensial dapat dibagikan dari subdomain yang berbeda
Chrome kini dapat mengambil kredensial yang disimpan di subdomain lain menggunakan
Credential Management API.
Misalnya, jika sandi disimpan di login.example.com
,
skrip di www.example.com
dapat menampilkannya sebagai salah satu item akun dalam 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 tersedia sebagai kredensial
di asal yang sama persis www.example.com
dan seterusnya.
Pada screenshot berikut, informasi kredensial yang disimpan di bagian login.aliexpress.com
dapat dilihat oleh m.aliexpress.com
dan tersedia untuk dipilih oleh 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 akan segera tidak digunakan lagi.navigator.credentials.get()
kini menerima enummediation
, bukan tanda booleanunmediated
.requireUserMediation()
diganti namanya menjadipreventSilentAccess()
.Metode baru
navigator.credentials.create()
membuat objek kredensial secara asinkron.
Deteksi fitur perlu diperhatikan
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 mengharuskan developer mengirim objek PasswordCredential
langsung ke server mereka untuk validasi melalui ekstensi ke fetch()
API.
Namun, pendekatan ini memperkenalkan sejumlah batasan. Kami menerima masukan bahwa developer tidak dapat menggunakan API karena:
Mereka harus mengirim sandi sebagai bagian dari objek JSON.
Mereka harus mengirim nilai hash sandi ke server mereka.
Setelah melakukan analisis keamanan dan menyadari bahwa menyembunyikan sandi dari JavaScript tidak mencegah semua vektor serangan seefektif yang kami harapkan, kami telah memutuskan untuk melakukan perubahan.
Credential Management API kini menyertakan sandi mentah dalam objek kredensial yang ditampilkan sehingga Anda memiliki akses ke sandi tersebut sebagai teks biasa. Anda dapat menggunakan metode yang 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
})
Sebaiknya gunakan fungsi fetch()
reguler seperti yang ditunjukkan dalam contoh kode sebelumnya,
atau gunakan XMLHttpRequest
.
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
});
Menetapkan unmediated: true
akan mencegah browser menampilkan pemilih akun
saat meneruskan kredensial.
Flag kini diperluas sebagai mediasi. Mediasi pengguna dapat terjadi jika:
Pengguna harus memilih akun yang akan digunakan 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 diteruskan tanpa menampilkan pemilih akun. | |
optional |
Sama dengan unmediated: false |
Menampilkan pemilih akun jika
preventSilentAccess() dipanggil sebelumnya. |
|
required |
Opsi baru | Selalu tampilkan pemilih akun. Berguna saat Anda ingin mengizinkan pengguna beralih akun menggunakan dialog pemilih akun native. |
Dalam contoh ini,
kredensial diteruskan tanpa menampilkan pemilih akun,
yang setara dengan flag 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 disebut 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()
Sekarang Anda memiliki opsi untuk membuat objek kredensial secara asinkron
dengan metode baru, navigator.credentials.create()
.
Baca terus untuk mengetahui perbandingan antara pendekatan sinkron 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 mengupgrade ke versi baru.