1. Skonfiguruj
Pobieranie kodu źródłowego
W ramach tego ćwiczenia w programie zaczniesz od przykładowej aplikacji Przyjazny czat, która jest prawie gotowa, więc najpierw musisz skopiować kod źródłowy:
$ git clone https://github.com/firebase/codelab-friendlychat-web --branch security
Następnie przejdź do katalogu security-start
, w którym będziesz pracować do końca tego ćwiczenia w programowaniu:
$ cd codelab-friendlychat-web/security-start
Teraz zainstaluj zależności, aby uruchomić kod. Jeśli masz wolniejsze połączenie, może to potrwać kilka minut:
$ npm install && (cd functions && npm install)
Zapoznaj się z tym repozytorium
Katalog security-solution/
zawiera pełny kod przykładowej aplikacji. Katalog security-start
to miejsce, w którym będziesz wykonywać ćwiczenia z programowania. Brakuje w nim kilku ważnych części implementacji uwierzytelniania. Najważniejsze pliki i funkcje w security-start/
i security-solution/
to:
functions/index.js
zawiera kod Cloud Functions i to w nim możesz pisać funkcje blokujące uwierzytelnianie.public/
– zawiera pliki statyczne aplikacji do obsługi czatupublic/scripts/main.js
– gdzie jest kompilowany kod JS aplikacji do obsługi czatu (src/index.js
)src/firebase-config.js
– zawiera obiekt konfiguracji Firebase używany do inicjowania aplikacji do obsługi czatu.src/index.js
– kod JS aplikacji do obsługi czatu
Pobieranie interfejsu wiersza poleceń Firebase
Pakiet emulatorów jest częścią interfejsu wiersza poleceń Firebase, który można zainstalować na komputerze za pomocą następującego polecenia:
$ npm install -g firebase-tools@latest
Utwórz kod JavaScript z pakietem webpack, który utworzy main.js w katalogu public/scripts/.
webpack build
Następnie sprawdź, czy masz najnowszą wersję interfejsu wiersza poleceń. To ćwiczenie w Codelabs działa w wersji 11.14 lub nowszej.
$ firebase --version 11.14.2
Połącz z projektem Firebase
Jeśli nie masz projektu Firebase, utwórz go w konsoli Firebase. Zanotuj wybrany identyfikator projektu, ponieważ będzie on potrzebny później.
Teraz musisz połączyć ten kod z projektem Firebase. Najpierw uruchom to polecenie, aby zalogować się w interfejsie wiersza poleceń Firebase:
$ firebase login
Następnie uruchom poniższe polecenie, aby utworzyć alias projektu. Zastąp $YOUR_PROJECT_ID
identyfikatorem projektu Firebase.
$ firebase use $YOUR_PROJECT_ID
Teraz możesz uruchomić aplikację.
2. Uruchamianie emulatorów
W tej sekcji uruchomisz aplikację lokalnie. Oznacza to, że pora uruchomić Pakiet emulatorów.
Uruchamianie emulatorów
W katalogu źródłowym ćwiczeń z programowania uruchom to polecenie, aby uruchomić emulatory:
$ firebase emulators:start
Spowoduje to udostępnienie aplikacji pod adresem http://127.0.0.1:5170 i ciągłe odbudowywanie kodu źródłowego podczas wprowadzania zmian. Aby zobaczyć zmiany, wystarczy nacisnąć twarde odświeżanie (Ctrl-Shift-r) lokalnie w przeglądarce.
Dane wyjściowe powinny wyglądać tak:
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
Gdy pojawi się komunikat All emulators ready (Wszystkie emulatory są gotowe), aplikacja będzie gotowa do użycia.
3. Wdrażanie MFA
MFA zostało częściowo wdrożone w tym repozytorium. Musisz dodać kod, aby najpierw zarejestrować użytkownika w MFA, a następnie wyświetlić użytkownikom zarejestrowanych w tym systemie prośbę o użycie drugiego składnika.
W edytorze otwórz plik src/index.js
i znajdź metodę startEnrollMultiFactor()
. Dodaj ten kod, aby skonfigurować weryfikatora reCAPTCHA, który będzie zapobiegać nadużyciom podczas korzystania z telefonu (weryfikator reCAPTCHA jest ustawiony jako niewidoczny i nie będzie widoczny dla użytkowników):
async function startEnrollMultiFactor(phoneNumber) {
const recaptchaVerifier = new RecaptchaVerifier(
"recaptcha",
{ size: "invisible" },
getAuth()
);
Następnie znajdź metodę finishEnrollMultiFactor()
i dodaj ten kod, aby zarejestrować 2 składnik:
// 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;
}
Następnie znajdź funkcję signIn
i dodaj poniższy proces sterowania, który prosi użytkowników zarejestrowanych w ramach MFA o podanie drugiego składnika:
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}`);
}
});
}
Pozostała część implementacji, w tym funkcje wywoływane tutaj, została już ukończona. Aby dowiedzieć się, jak działają, przejrzyj pozostałą część pliku.
4. Spróbuj zalogować się w emulatorach z użyciem MFA
Teraz wypróbuj implementację MFA. Sprawdź, czy emulatory nadal działają, i otwórz aplikację hostowaną lokalnie pod adresem localhost:5170
. Spróbuj się zalogować. Gdy pojawi się prośba o podanie kodu MFA, zobaczysz go w oknie terminala.
Ponieważ emulatory w pełni obsługują uwierzytelnianie wielopoziomowe, środowisko programistyczne może być całkowicie niezależne.
Więcej informacji o implementowaniu MFA znajdziesz w dokumentacji referencyjnej.
5. Tworzenie funkcji blokującej
Niektóre aplikacje są przeznaczone dla określonej grupy użytkowników. W takich przypadkach warto mieć możliwość utworzenia niestandardowych wymagań dotyczących rejestracji lub logowania się w aplikacji.
Właśnie to zapewniają funkcje blokowania: pozwalają tworzyć niestandardowe wymagania dotyczące uwierzytelniania. To funkcje w Cloud Functions, ale w przeciwieństwie do większości funkcji działają synchronicznie, gdy użytkownik próbuje się zarejestrować lub zalogować.
Aby utworzyć funkcję blokującą, otwórz w edytorze functions/index.js
i znajdź funkcję beforecreated
z komentarzem.
Zastąp go kodem, który pozwala na tworzenie kont tylko użytkownikom należącym do domeny example.com:
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. Wypróbuj funkcję blokowania w emulatorach
Aby wypróbować funkcję blokowania, sprawdź, czy emulatory są uruchomione, i wyloguj się z aplikacji internetowej na stronie localhost:5170
.
Następnie spróbuj utworzyć konto z adresem e-mail, który nie kończy się na example.com
. Funkcja blokująca uniemożliwi wykonanie operacji.
Spróbuj ponownie, używając adresu e-mail, który kończy się na example.com
. Konto zostanie utworzone.
Dzięki funkcjom blokowania możesz tworzyć wszelkie potrzebne ograniczenia dotyczące uwierzytelniania. Więcej informacji znajdziesz w dokumentacji.
Podsumowanie
Brawo! Dodałeś uwierzytelnianie wielopoziomowe do aplikacji internetowej, aby zwiększyć bezpieczeństwo użytkowników, i stworzyliśmy niestandardowe wymagania dotyczące rejestracji przy użyciu funkcji blokowania. Bez wątpienia otrzymujesz GIF-a.