Update terbaru pada API pengelolaan kredensial

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:

Pemilih akun yang menampilkan detail login subdomain yang dipilih

Chrome 60

Chrome 60 memperkenalkan beberapa perubahan penting pada Credential Management API:

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.

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.