1. Siapkan
Mendapatkan kode sumber
Dalam codelab ini, Anda akan memulai dengan versi aplikasi contoh Friendly Chat yang hampir selesai, jadi hal pertama yang perlu Anda lakukan adalah meng-clone kode sumber:
$ git clone https://github.com/firebase/codelab-friendlychat-web --branch security
Kemudian, beralihlah ke direktori security-start
, tempat Anda akan bekerja selama sisa codelab ini:
$ cd codelab-friendlychat-web/security-start
Sekarang, instal dependensi agar Anda dapat menjalankan kode. Jika Anda menggunakan koneksi internet yang lebih lambat, proses ini mungkin memerlukan waktu satu atau dua menit:
$ npm install && (cd functions && npm install)
Mengenali repo ini
Direktori security-solution/
berisi kode lengkap untuk aplikasi contoh. Direktori security-start
adalah tempat Anda akan mengerjakan codelab, dan tidak memiliki beberapa bagian penting dari implementasi autentikasi. File dan fitur utama di security-start/
dan security-solution/
adalah:
functions/index.js
berisi kode Cloud Functions, dan di sinilah Anda akan menulis fungsi pemblokiran autentikasi.public/
- berisi file statis untuk aplikasi chat Andapublic/scripts/main.js
- tempat kode JS aplikasi chat (src/index.js
) dikompilasi untuksrc/firebase-config.js
- berisi objek konfigurasi Firebase yang digunakan untuk menginisialisasi aplikasi chat Andasrc/index.js
- kode JS aplikasi chat Anda
Mendapatkan Firebase CLI
Emulator Suite adalah bagian dari Firebase CLI (antarmuka command line), yang dapat diinstal di komputer Anda dengan perintah berikut:
$ npm install -g firebase-tools@latest
Build javascript dengan webpack, yang akan membuat main.js di dalam direktori public/scripts/.
webpack build
Selanjutnya, pastikan Anda memiliki CLI versi terbaru. Codelab ini berfungsi dengan versi 11.14 atau yang lebih baru.
$ firebase --version 11.14.2
Hubungkan ke project Firebase Anda
Jika Anda belum memiliki project Firebase, di Firebase console, buat project Firebase baru. Catat Project ID yang Anda pilih, karena Anda akan memerlukannya nanti.
Sekarang Anda perlu menghubungkan kode ini ke project Firebase. Pertama, jalankan perintah berikut untuk login ke Firebase CLI:
$ firebase login
Selanjutnya, jalankan perintah berikut untuk membuat alias project. Ganti $YOUR_PROJECT_ID
dengan ID project Firebase Anda.
$ firebase use $YOUR_PROJECT_ID
Sekarang Anda siap untuk menjalankan aplikasi.
2. Menjalankan emulator
Di bagian ini, Anda akan menjalankan aplikasi secara lokal. Ini berarti saatnya untuk mem-booting Emulator Suite.
Memulai Emulator
Dari dalam direktori sumber codelab, jalankan perintah berikut untuk memulai emulator:
$ firebase emulators:start
Ini akan menayangkan aplikasi Anda di http://127.0.0.1:5170 dan terus membangun ulang kode sumber saat Anda membuat perubahan. Anda hanya perlu melakukan refresh paksa (ctrl-shift-r) secara lokal di browser untuk melihat perubahan.
Anda akan melihat output seperti ini:
i emulators: Starting emulators: auth, functions, firestore, hosting, storage ✔ functions: Using node@16 from host. i firestore: Firestore Emulator logging to firestore-debug.log ✔ firestore: Firestore Emulator UI websocket is running on 9150. i hosting[demo-example]: Serving hosting files from: ./public ✔ hosting[demo-example]: Local server: http://127.0.0.1:5170 i ui: Emulator UI logging to ui-debug.log i functions: Watching "[...]" for Cloud Functions... ✔ functions: Loaded functions definitions from source: beforecreated. ✔ functions[us-central1-beforecreated]: providers/cloud.auth/eventTypes/user.beforeCreate function initialized (http://127.0.0.1:5011/[...]/us-central1/beforecreated). i Running script: npm start > security@1.0.0 start > webpack --watch --progress [...] webpack 5.50.0 compiled with 1 warning in 990 ms
Setelah Anda melihat pesan Semua emulator siap, aplikasi siap digunakan.
3. Menerapkan MFA
MFA telah diterapkan sebagian dalam repo ini. Anda harus menambahkan kode untuk mendaftarkan pengguna di MFA terlebih dahulu, lalu meminta pengguna yang terdaftar di MFA untuk faktor kedua.
Di editor, buka file src/index.js
dan temukan metode startEnrollMultiFactor()
. Tambahkan kode berikut untuk menyiapkan pemverifikasi reCAPTCHA yang akan mencegah penyalahgunaan telepon (pemverifikasi reCAPTCHA disetel ke tidak terlihat dan tidak akan terlihat oleh pengguna):
async function startEnrollMultiFactor(phoneNumber) {
const recaptchaVerifier = new RecaptchaVerifier(
"recaptcha",
{ size: "invisible" },
getAuth()
);
Kemudian, cari metode finishEnrollMultiFactor()
dan tambahkan kode berikut untuk mendaftarkan faktor kedua:
// Completes MFA enrollment once a verification code is obtained.
async function finishEnrollMultiFactor(verificationCode) {
// Ask user for the verification code. Then:
const cred = PhoneAuthProvider.credential(verificationId, verificationCode);
const multiFactorAssertion = PhoneMultiFactorGenerator.assertion(cred);
// Complete enrollment.
await multiFactor(getAuth().currentUser)
.enroll(multiFactorAssertion)
.catch(function (error) {
alert(`Error finishing second factor enrollment. ${error}`);
throw error;
});
verificationId = null;
}
Selanjutnya, temukan fungsi signIn
dan tambahkan alur kontrol berikut yang meminta pengguna yang terdaftar di MFA untuk memasukkan faktor kedua mereka:
async function signIn() {
// Sign in Firebase using popup auth and Google as the identity provider.
var provider = new GoogleAuthProvider();
await signInWithPopup(getAuth(), provider)
.then(function (userCredential) {
// User successfully signed in and is not enrolled with a second factor.
})
.catch(function (error) {
if (error.code == "auth/multi-factor-auth-required") {
multiFactorResolver = getMultiFactorResolver(getAuth(), error);
displaySecondFactor(multiFactorResolver.hints);
} else {
alert(`Error signing in user. ${error}`);
}
});
}
Implementasi lainnya, termasuk fungsi yang dipanggil di sini, sudah selesai. Untuk melihat cara kerjanya, telusuri sisa file tersebut.
4. Mencoba login dengan MFA di emulator
Sekarang cobalah penerapan MFA. Pastikan emulator Anda masih berjalan dan buka aplikasi yang dihosting secara lokal di localhost:5170
. Coba login, dan saat diminta untuk memberikan kode MFA, Anda akan melihat kode MFA di jendela terminal.
Karena emulator sepenuhnya mendukung Multi-Faktor Auth, lingkungan pengembangan Anda bisa sepenuhnya mandiri.
Untuk mempelajari lebih lanjut cara menerapkan MFA, lihat dokumen referensi kami.
5. Membuat fungsi pemblokiran
Beberapa aplikasi dimaksudkan untuk hanya digunakan oleh grup pengguna tertentu. Untuk kasus tersebut, Anda ingin dapat membuat persyaratan kustom bagi pengguna untuk mendaftar atau login ke aplikasi Anda.
Itulah yang disediakan oleh fungsi pemblokiran: cara untuk membuat persyaratan autentikasi kustom. Cloud Functions adalah Cloud Functions. Namun, tidak seperti kebanyakan fungsi, Cloud Functions berjalan secara sinkron saat pengguna mencoba mendaftar atau login.
Untuk membuat fungsi pemblokiran, buka functions/index.js
di editor dan temukan fungsi beforecreated
yang dikomentari.
Ganti dengan kode ini yang hanya mengizinkan pengguna dengan domain example.com untuk membuat akun:
exports.beforecreated = beforeUserCreated((event) => {
const user = event.data;
// Only users of a specific domain can sign up.
if (!user.email || !user.email.endsWith("@example.com")) {
throw new HttpsError("invalid-argument", "Unauthorized email");
}
});
6. Mencoba fungsi pemblokiran di emulator
Untuk mencoba fungsi pemblokiran, pastikan emulator Anda berjalan, dan logout di aplikasi web pada localhost:5170
.
Kemudian, coba buat akun dengan alamat email yang tidak berakhiran example.com
. Fungsi pemblokiran akan mencegah keberhasilan operasi.
Sekarang, coba lagi dengan alamat email yang berakhiran example.com
. Akun akan berhasil dibuat.
Dengan fungsi pemblokiran, Anda dapat membuat batasan yang diperlukan seputar autentikasi. Untuk mempelajari lebih lanjut, lihat dokumen referensi.
Rangkuman
Bagus sekali. Anda telah menambahkan Autentikasi Multi-Faktor ke aplikasi web untuk membantu pengguna menjaga keamanan akun mereka, lalu Anda membuat persyaratan khusus bagi pengguna untuk mendaftar menggunakan fungsi pemblokiran. Anda pasti mendapatkan gif.