Update terbaru pada API pengelolaan kredensial

Beberapa pembaruan yang dijelaskan di sini dijelaskan dalam sesi Google I/O, Login dengan Aman dan Lancar: Menjaga Pengguna Tetap Berinteraksi:

Chrome 57

Chrome 57 memperkenalkan perubahan penting ini pada Credential Management API.

Kredensial dapat dibagikan dari subdomain yang berbeda

Chrome sekarang dapat mengambil kredensial yang disimpan di subdomain yang berbeda 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 secara eksplisit menyimpan sandi menggunakan navigator.credentials.store(), sehingga ketika pengguna memilih kredensial dengan mengetuk dialog, {i>password<i}-nya diteruskan dan disalin ke asal saat ini.

Setelah disimpan, sandi akan tersedia sebagai kredensial dalam origin yang sama persis, www.example.com dan seterusnya.

Dalam screenshot berikut, informasi kredensial disimpan di login.aliexpress.com dapat dilihat oleh m.aliexpress.com dan tersedia bagi pengguna untuk memilih:

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 berbasis {i>password<i} dan kredensial 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 mengambil pendekatan konservatif untuk menangani sandi. Enkripsi ini menyembunyikan sandi dari JavaScript, sehingga mengharuskan developer untuk mengirim objek PasswordCredential langsung ke server untuk validasi melalui ekstensi ke fetch() API.

Namun, pendekatan ini memasukkan sejumlah batasan. Kami menerima masukan bahwa developer tidak dapat menggunakan API karena:

  • Mereka harus mengirimkan sandi sebagai bagian dari objek JSON.

  • Mereka harus mengirimkan nilai {i> hash <i}dari {i>password<i} ke server mereka.

Setelah melakukan analisis keamanan dan menyadari bahwa menyembunyikan {i>password<i} dari JavaScript tidak mencegah semua vektor serangan seefektif yang kita harapkan, kami telah memutuskan untuk melakukan perubahan.

Credential Management API kini menyertakan sandi mentah dalam objek kredensial yang ditampilkan sehingga Anda memiliki akses 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 kueri tersebut menggunakan objek PasswordCredential atau objek FederatedCredential sebagai nilai properti credentials, misalnya:

fetch('/signin', {
    method: 'POST',
    credentials: c
})

Dengan menggunakan fungsi fetch() biasa seperti yang ditunjukkan dalam contoh kode sebelumnya, atau menggunakan 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 sekarang diperluas sebagai mediasi. Mediasi pengguna dapat terjadi jika:

  • Pengguna harus memilih akun yang akan digunakan untuk login.

  • Seorang pengguna ingin login secara eksplisit setelah panggilan navigator.credentials.requireUseMediation().

Pilih salah satu opsi berikut untuk nilai mediation:

Nilai mediation Dibandingkan dengan tanda boolean Perilaku
silent Sama dengan unmediated: true Kredensial lulus tanpa menampilkan pemilih akun.
optional Sama dengan unmediated: false Menampilkan pemilih akun jika preventSilentAccess() telah 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 menunjukkan pemilih akun, 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 satu sumber dan tidak ingin masuk kembali secara otomatis pada kunjungan berikutnya.

signoutUser();
if (navigator.credentials) {
    navigator.credentials.preventSilentAccess();
}

Membuat objek kredensial secara asinkron dengan metode baru navigator.credentials.create()

Anda kini 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 meningkatkan ke versi baru.