Update terbaru pada API pengelolaan kredensial

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:

Pemilih akun yang menampilkan detail login subdomain yang dipilih

Chrome 60

Chrome 60 memperkenalkan beberapa perubahan penting pada Credential Management API:

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.

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.