Menyederhanakan alur login menggunakan API pengelolaan kredensial

Untuk memberikan pengalaman pengguna yang canggih, Anda harus membantu pengguna melakukan autentikasi ke situs Anda. Pengguna yang diautentikasi dapat berinteraksi satu sama lain menggunakan profil khusus, menyinkronkan data di seluruh perangkat, atau memproses data saat offline; daftarnya terus bertambah. Namun, membuat, mengingat, dan mengetik sandi cenderung merepotkan bagi pengguna akhir, terutama di layar seluler yang menyebabkan mereka menggunakan kembali sandi yang sama di berbagai situs. Hal ini tentu saja merupakan risiko keamanan.

Chrome versi terbaru (51) mendukung Credential Management API. Ini adalah proposal jalur standar di W3C yang memberi developer akses terprogram ke pengelola kredensial browser dan membantu pengguna login dengan lebih mudah.

Apa yang dimaksud dengan Credential Management API?

Credential Management API memungkinkan developer menyimpan dan mengambil kredensial sandi dan kredensial gabungan serta menyediakan 3 fungsi:

  • navigator.credentials.get()
  • navigator.credentials.store()
  • navigator.credentials.requireUserMediation()

Dengan menggunakan API sederhana ini, developer dapat melakukan hal-hal yang efektif seperti:

  • Izinkan pengguna login hanya dengan sekali ketuk.
  • Ingat akun gabungan yang digunakan pengguna untuk login.
  • Meminta pengguna untuk login kembali saat sesi berakhir.

Dalam penerapan Chrome, kredensial akan disimpan di pengelola sandi Chrome. Jika pengguna login ke Chrome, mereka dapat menyinkronkan sandi pengguna di seluruh perangkat. Sandi yang disinkronkan tersebut juga dapat dibagikan ke aplikasi Android yang telah mengintegrasikan Smart Lock for Passwords API for Android untuk pengalaman lintas platform yang lancar.

Mengintegrasikan Credential Management API dengan situs Anda

Cara Anda menggunakan Credential Management API dengan situs dapat bervariasi bergantung pada arsitekturnya. Apakah ini aplikasi web satu halaman? Apakah ini adalah arsitektur lama dengan transisi halaman? Apakah formulir login hanya terletak di halaman atas? Apakah tombol login ada di mana-mana? Dapatkah pengguna menjelajahi situs Anda dengan bermakna tanpa login? Apakah federasi berfungsi dalam jendela pop-up? Atau apakah memerlukan interaksi di beberapa halaman?

Hampir tidak mungkin untuk membahas semua kasus tersebut, tetapi mari kita lihat aplikasi web satu halaman yang umum.

  • Halaman atas adalah formulir pendaftaran.
  • Dengan mengetuk tombol "Login", pengguna akan diarahkan ke formulir login.
  • Formulir pendaftaran dan login memiliki opsi kredensial ID/sandi dan federasi yang umum, misalnya dengan Login dengan Google dan Login dengan Facebook.

Dengan menggunakan Credential Management API, Anda dapat menambahkan fitur berikut ke situs, misalnya:

  • Menampilkan pemilih akun saat login: Menampilkan UI pemilih akun native saat pengguna mengetuk "Login".
  • Menyimpan kredensial: Setelah login berhasil, tawarkan untuk menyimpan informasi kredensial ke pengelola sandi browser untuk digunakan nanti.
  • Memungkinkan pengguna login kembali secara otomatis: Memungkinkan pengguna login kembali jika sesi telah berakhir.
  • Mediasi login otomatis: Setelah pengguna logout, nonaktifkan login otomatis untuk kunjungan pengguna berikutnya.

Anda dapat merasakan fitur ini yang diterapkan di situs demo dengan kode contohnya.

Menampilkan Pemilih Akun saat login

Antara ketukan pengguna pada tombol "Login" dan navigasi ke formulir login, Anda dapat menggunakan navigator.credentials.get() untuk mendapatkan informasi kredensial. Chrome akan menampilkan UI pemilih akun tempat pengguna dapat memilih akun.

UI pemilih akun akan muncul agar pengguna dapat memilih akun untuk login.
UI pemilih akun muncul agar pengguna dapat memilih akun untuk login

Mendapatkan objek kredensial sandi

Untuk menampilkan kredensial sandi sebagai opsi akun, gunakan password: true.

navigator.credentials.get({
    password: true, // `true` to obtain password credentials
}).then(function(cred) {
    // continuation
    ...

Menggunakan kredensial sandi untuk login

Setelah pengguna membuat pilihan akun, fungsi penyelesaian akan menerima kredensial sandi. Anda dapat mengirimkannya ke server menggunakan fetch():

    // continued from previous example
}).then(function(cred) {
    if (cred) {
    if (cred.type == 'password') {
        // Construct FormData object
        var form = new FormData();

        // Append CSRF Token
        var csrf_token = document.querySelector('csrf_token').value;
        form.append('csrf_token', csrf_token);

        // You can append additional credential data to `.additionalData`
        cred.additionalData = form;

        // `POST` the credential object as `credentials`.
        // id, password and the additional data will be encoded and
        // sent to the url as the HTTP body.
        fetch(url, {           // Make sure the URL is HTTPS
        method: 'POST',      // Use POST
        credentials: cred    // Add the password credential object
        }).then(function() {
        // continuation
        });
    } else if (cred.type == 'federated') {
        // continuation

Menggunakan kredensial gabungan untuk login

Untuk menampilkan akun gabungan kepada pengguna, tambahkan federated, yang menggunakan array penyedia identitas, ke opsi get().

Jika beberapa akun disimpan di pengelola sandi.
Saat beberapa akun disimpan di pengelola sandi
navigator.credentials.get({
    password: true, // `true` to obtain password credentials
    federated: {
    providers: [  // Specify an array of IdP strings
        'https://accounts.google.com',
        'https://www.facebook.com'
    ]
    }
}).then(function(cred) {
    // continuation
    ...

Anda dapat memeriksa properti type objek kredensial untuk melihat apakah kredensial tersebut adalah PasswordCredential (type == 'password') atau FederatedCredential (type == 'federated'). Jika kredensial adalah FederatedCredential, Anda dapat memanggil API yang sesuai menggunakan informasi yang dikandungnya.

    });
} else if (cred.type == 'federated') {
    // `provider` contains the identity provider string
    switch (cred.provider) {
    case 'https://accounts.google.com':
        // Federated login using Google Sign-In
        var auth2 = gapi.auth2.getAuthInstance();

        // In Google Sign-In library, you can specify an account.
        // Attempt to sign in with by using `login_hint`.
        return auth2.signIn({
        login_hint: cred.id || ''
        }).then(function(profile) {
        // continuation
        });
        break;

    case 'https://www.facebook.com':
        // Federated login using Facebook Login
        // continuation
        break;

    default:
        // show form
        break;
    }
}
// if the credential is `undefined`
} else {
// show form
Diagram alir pengelolaan kredensial.

Menyimpan kredensial

Saat pengguna login ke situs Anda menggunakan formulir, Anda dapat menggunakan navigator.credentials.store() untuk menyimpan kredensial. Pengguna akan diminta untuk menyimpannya atau tidak. Bergantung pada jenis kredensial, gunakan new PasswordCredential() atau new FederatedCredential() untuk membuat objek kredensial yang ingin Anda simpan.

Chrome akan menanyakan kepada pengguna apakah mereka ingin menyimpan kredensial (atau penyedia gabungan).
Chrome akan meminta pengguna apakah mereka ingin menyimpan kredensial (atau penyedia gabungan)

Membuat dan menyimpan kredensial sandi dari elemen formulir

Kode berikut menggunakan atribut autocomplete untuk secara otomatis memetakan elemen formulir ke parameter objek PasswordCredential.

HTML html <form id="form" method="post"> <input type="text" name="id" autocomplete="username" /> <input type="password" name="password" autocomplete="current-password" /> <input type="hidden" name="csrf_token" value="******" /> </form>

JavaScript

var form = document.querySelector('\#form');
var cred = new PasswordCredential(form);
// Store it
navigator.credentials.store(cred)
.then(function() {
    // continuation
});

Membuat dan menyimpan kredensial gabungan

// After a federation, create a FederatedCredential object using
// information you have obtained
var cred = new FederatedCredential({
    id: id,                                  // The id for the user
    name: name,                              // Optional user name
    provider: 'https://accounts.google.com',  // A string that represents the identity provider
    iconURL: iconUrl                         // Optional user avatar image url
});
// Store it
navigator.credentials.store(cred)
.then(function() {
    // continuation
});
Diagram alur login.

Mengizinkan pengguna login kembali secara otomatis

Saat pengguna meninggalkan situs Anda dan kembali lagi nanti, mungkin sesi tersebut telah berakhir. Jangan repotkan pengguna untuk mengetik sandi setiap kali mereka kembali. Izinkan pengguna login kembali secara otomatis.

Saat pengguna login secara otomatis, notifikasi akan muncul.
Saat pengguna login secara otomatis, notifikasi akan muncul.

Mendapatkan objek kredensial

navigator.credentials.get({
    password: true, // Obtain password credentials or not
    federated: {    // Obtain federation credentials or not
    providers: [  // Specify an array of IdP strings
        'https://accounts.google.com',
        'https://www.facebook.com'
    ]
    },
    unmediated: true // `unmediated: true` lets the user automatically sign in
}).then(function(cred) {
    if (cred) {
    // auto sign-in possible
    ...
    } else {
    // auto sign-in not possible
    ...
    }
});

Kode akan terlihat mirip dengan yang Anda lihat di bagian "Tampilkan Pemilih Akun saat Login". Satu-satunya perbedaan adalah Anda akan menetapkan unmediated: true.

Tindakan ini akan segera me-resolve fungsi dan memberi Anda kredensial untuk membuat pengguna login secara otomatis. Ada beberapa kondisi:

  • Pengguna telah mengonfirmasi fitur login otomatis dengan sambutan hangat.
  • Pengguna sebelumnya telah login ke situs menggunakan Credential Management API.
  • Pengguna hanya memiliki satu kredensial yang disimpan untuk origin Anda.
  • Pengguna tidak logout secara eksplisit di sesi sebelumnya.

Jika salah satu kondisi ini tidak terpenuhi, fungsi akan ditolak.

Diagram alur objek kredensial

Memediasi login otomatis

Saat pengguna logout dari situs Anda, Anda bertanggung jawab untuk memastikan bahwa pengguna tidak akan otomatis login kembali. Untuk memastikan hal ini, Credential Management API menyediakan mekanisme yang disebut mediasi. Anda dapat mengaktifkan mode mediasi dengan memanggil navigator.credentials.requireUserMediation(). Selama status mediasi pengguna untuk origin diaktifkan, menggunakan unmediated: true dengan navigator.credentials.get(), fungsi tersebut akan di-resolve dengan undefined.

Memediasi login otomatis

navigator.credentials.requireUserMediation();
Diagram alur login otomatis.

FAQ

Apakah JavaScript di situs dapat mengambil sandi mentah? Tidak. Anda hanya dapat memperoleh sandi sebagai bagian dari PasswordCredential dan tidak dapat diekspos dengan cara apa pun.

Apakah 3 kumpulan angka untuk ID dapat disimpan menggunakan Credential Management API? Untuk saat ini, tidak. Masukan Anda terkait spesifikasi akan sangat kami hargai.

Dapatkah saya menggunakan Credential Management API di dalam iframe? API dibatasi untuk konteks tingkat atas. Panggilan ke .get() atau .store() dalam iframe akan segera di-resolve tanpa efek.

Dapatkah saya mengintegrasikan ekstensi Chrome pengelolaan sandi dengan Credential Management API? Anda dapat mengganti navigator.credentials dan menghubungkannya ke Ekstensi Chrome untuk kredensial get() atau store().

Resource

Untuk mempelajari Credential Management API lebih lanjut, lihat Panduan Integrasi.