Menyederhanakan alur login menggunakan API pengelolaan kredensial

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

Versi terbaru Chrome (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 itu 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 canggih seperti:

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

Dalam implementasi 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 untuk Android untuk pengalaman lintas platform yang lancar.

Mengintegrasikan Credential Management API dengan situs

Cara Anda menggunakan Credential Management API dengan situs dapat bervariasi bergantung pada arsitekturnya. Apakah aplikasi tersebut merupakan aplikasi web satu halaman? Apakah itu arsitektur lama dengan transisi laman? Apakah formulir login hanya terletak di halaman atas? Apakah tombol login ada di mana-mana? Dapatkah pengguna menjelajahi {i>website<i} Anda dengan cara yang bermakna tanpa harus {i>login<i}? Apakah penggabungan berfungsi dalam jendela pop-up? Atau apakah dibutuhkan interaksi di beberapa laman?

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

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

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

  • Tampilkan pemilih akun saat login: Menampilkan UI pemilih akun native saat pengguna mengetuk "Login".
  • Simpan kredensial: Setelah login berhasil, tawarkan untuk menyimpan informasi kredensial ke pengelola sandi browser untuk digunakan nanti.
  • Izinkan pengguna login kembali secara otomatis: Mengizinkan pengguna login kembali jika sesi sudah berakhir.
  • Memediasi login otomatis: Setelah pengguna logout, nonaktifkan login otomatis untuk kunjungan pengguna berikutnya.

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

Tampilkan Pemilih Akun saat login

Dengan mengetuk 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 akan 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().

Saat 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 mengetahui apakah properti tersebut adalah PasswordCredential (type == 'password') atau FederatedCredential (type == 'federated'). Jika kredensial adalah FederatedCredential, Anda dapat memanggil API yang sesuai menggunakan informasi yang ada di dalamnya.

    });
} 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 alur pengelolaan kredensial.

Simpan kredensial

Ketika 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 menanyakan apakah pengguna ingin menyimpan kredensial (atau penyedia gabungan)

Membuat dan menyimpan kredensial sandi dari elemen formulir

Kode berikut menggunakan atribut autocomplete untuk 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 keluar dari situs Anda dan kemudian kembali lagi, mungkin masa berlaku sesi telah berakhir. Jangan mengganggu 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 seperti yang ada 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 memproses login pengguna secara otomatis. Ada beberapa kondisi:

  • Pengguna telah mengonfirmasi fitur login otomatis dengan sambutan yang 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 tersebut tidak terpenuhi, fungsi akan ditolak.

Diagram alur objek kredensial

Memediasi login otomatis

Saat pengguna logout dari situs Anda, Anda bertanggung jawab untuk memastikan pengguna tidak akan login kembali secara otomatis. 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 diselesaikan 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 sandi tidak dapat dilihat dengan cara apa pun.

Apakah saya dapat menyimpan 3 kumpulan digit untuk sebuah ID menggunakan Credential Management API? Untuk saat ini, tidak. Masukan Anda terkait spesifikasi akan sangat dihargai.

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

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

Referensi

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