Funkcje blokowania umożliwiają uruchamianie niestandardowego kodu, który zmienia wynik rejestracji lub logowania się użytkownika w aplikacji. Możesz na przykład uniemożliwić użytkownikowi uwierzytelnianie, jeśli nie spełnia określonych kryteriów, lub zaktualizować informacje o użytkowniku przed zwróceniem go do aplikacji klienckiej.
Zanim zaczniesz
Aby korzystać z funkcji blokowania, musisz uaktualnić projekt Firebase do wersji Firebase Authentication with Identity Platform. Jeśli nie masz jeszcze uaktualnionej wersji, najpierw to zrób.
Funkcje blokowania
Funkcję blokowania możesz zarejestrować w przypadku tych zdarzeń:
beforeCreate
: uruchamia się przed zapisaniem nowego użytkownika w bazie danych Firebase Authentication i przed zwróceniem tokena do aplikacji klienta.beforeSignIn
: funkcja jest wywoływana po zweryfikowaniu danych logowania użytkownika, ale przed Firebase Authentication zwróceniem tokena identyfikacyjnego do aplikacji klienckiej. Jeśli Twoja aplikacja korzysta z uwierzytelniania wielopoziomowego, funkcja jest wywoływana po zweryfikowaniu przez użytkownika drugiego czynnika. Pamiętaj, że utworzenie nowego użytkownika powoduje również wywołanie regułybeforeSignIn
, a nie tylkobeforeCreate
.beforeEmail
(dotyczy tylko Node.js): uruchamia się przed wysłaniem do użytkownika e-maila (np.
e-maila z linkiem do logowania lub resetowania hasła).beforeSms
(dotyczy tylko Node.js): uruchamia się przed wysłaniem wiadomości SMS do użytkownika, na przykład w przypadku uwierzytelniania wielopoziomowego.
Korzystając z funkcji blokowania, pamiętaj o tych kwestiach:
Funkcja musi odpowiedzieć w ciągu 7 sekund. Po 7 sekundach funkcja Firebase Authentication zwraca błąd, a operacja klienta kończy się niepowodzeniem.
Kody odpowiedzi HTTP inne niż
200
są przekazywane do aplikacji klienckich. Upewnij się, że kod klienta obsługuje wszystkie błędy, które funkcja może zwrócić.Funkcje mają zastosowanie do wszystkich użytkowników w projekcie, w tym do wszystkich użytkowników w ramach najemcy. Firebase Authentication udostępnia Twojej funkcji informacje o użytkownikach, w tym o ich domenach, aby umożliwić Ci odpowiednie działanie.
Połączenie innego dostawcy tożsamości z kontem powoduje ponowne uruchomienie wszystkich zarejestrowanych funkcji
beforeSignIn
.Anonimowe i niestandardowe uwierzytelnianie nie powoduje blokowania funkcji.
Wdrażanie funkcji blokującej
Aby wstawić kod niestandardowy do procesów uwierzytelniania użytkownika, wdróż funkcje blokowania. Gdy funkcje blokowania zostaną wdrożone, niestandardowy kod musi zostać uruchomiony, aby uwierzytelnianie i tworzenie użytkownika przebiegło pomyślnie.
Funkcję blokującą wdraża się tak samo jak każdą inną funkcję. (szczegóły znajdziesz na stronie Cloud Functions Pierwsze kroki). W skrócie:
Napisz funkcję, która obsługuje wybrane zdarzenie.
Na przykład na początek możesz dodać do
index.js
funkcję no-op taką jak poniżej:const functions = require('firebase-functions/v1'); exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => { // TODO }); The above example has omitted the implementation of custom auth logic. See the following sections to learn how to implement your blocking functions and [Common scenarios](#common-scenarios) for specific examples.
Wdróż funkcje za pomocą interfejsu wiersza poleceń Firebase:
firebase deploy --only functions
Za każdym razem, gdy aktualizujesz funkcje, musisz je ponownie wdrożyć.
Uzyskiwanie informacji o użytkowniku i kontekstu
Zdarzenia beforeSignIn
i beforeCreate
udostępniają obiekty User
i EventContext
, które zawierają informacje o logowaniu użytkownika. Użyj tych wartości w kodze, aby określić, czy operacja może być kontynuowana.
Listę właściwości dostępnych w obiekcie User
znajdziesz w dokumentacji interfejsu API UserRecord
.
Obiekt EventContext
zawiera te właściwości:
Nazwa | Opis | Przykład |
---|---|---|
locale |
Język aplikacji. Możesz ustawić język za pomocą pakietu SDK klienta lub przekazując nagłówek locale w interfejsie REST API. | fr lub sv-SE |
ipAddress
| Adres IP urządzenia, na którym użytkownik rejestruje się lub loguje. | 114.14.200.1 |
userAgent
| Klient użytkownika aktywujący funkcję blokowania. | Mozilla/5.0 (X11; Linux x86_64) |
eventId
| Unikalny identyfikator zdarzenia. | rWsyPtolplG2TBFoOkkgyg |
eventType
|
Typ zdarzenia. Zobaczysz informacje o nazwie zdarzenia, np. beforeSignIn lub beforeCreate , oraz o powiązanej metodzie logowania, np. za pomocą konta Google, lub o adresie e-mail i haśle.
|
providers/cloud.auth/eventTypes/user.beforeSignIn:password
|
authType
| Zawsze USER . |
USER
|
resource
| Projekt lub najemca Firebase Authentication. |
projects/project-id/tenants/tenant-id
|
timestamp
| Czas wywołania zdarzenia sformatowany jako ciąg znaków zgodnie ze specyfikacją RFC 3339. | Tue, 23 Jul 2019 21:10:57 GMT
|
additionalUserInfo
| Obiekt zawierający informacje o użytkowniku. |
AdditionalUserInfo
|
credential
| Obiekt zawierający informacje o danych logowania użytkownika. |
AuthCredential
|
Blokowanie rejestracji lub logowania
Aby zablokować próbę rejestracji lub logowania, użyj funkcji HttpsError
w swojej funkcji. Przykład:
Node.js
throw new functions.auth.HttpsError('permission-denied');
W tabeli poniżej znajdziesz listę błędów, które mogą wystąpić, wraz z domyślnym komunikatem o błędzie:
Nazwa | Kod | Wiadomość |
---|---|---|
invalid-argument |
400 |
Klient podał nieprawidłowy argument. |
failed-precondition |
400 |
Żądania nie można wykonać przy aktualnym stanie systemu. |
out-of-range |
400 |
Klient podał nieprawidłowy zakres. |
unauthenticated |
401 |
Brakujący, nieprawidłowy lub wygasły token OAuth. |
permission-denied |
403 |
Klient nie ma wystarczających uprawnień. |
not-found |
404 |
Nie udało się znaleźć podanego zasobu. |
aborted |
409 |
Konflikt równoczesności, na przykład konflikt odczytu-modyfikacji-zapisu. |
already-exists |
409 |
Zasób, który próbował utworzyć klient, już istnieje. |
resource-exhausted |
429 |
Limit zasobu został wyczerpany lub usługa aktywuje ograniczanie liczby żądań. |
cancelled |
499 |
Żądanie anulowane przez klienta. |
data-loss |
500 |
Nieodwracalna utrata danych lub ich uszkodzenie. |
unknown |
500 |
Nieznany błąd serwera. |
internal |
500 |
Wewnętrzny błąd serwera. |
not-implemented |
501 |
Metoda interfejsu API nie została zaimplementowana przez serwer. |
unavailable |
503 |
Usługa niedostępna |
deadline-exceeded |
504 |
Upłynął termin realizacji żądania. |
Możesz też podać niestandardowy komunikat o błędzie:
Node.js
throw new functions.auth.HttpsError('permission-denied', 'Unauthorized request origin!');
Poniższy przykład pokazuje, jak zablokować możliwość rejestracji w aplikacji użytkownikom spoza określonej domeny:
Node.js
exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
// (If the user is authenticating within a tenant context, the tenant ID can be determined from
// user.tenantId or from context.resource, e.g. 'projects/project-id/tenant/tenant-id-1')
// Only users of a specific domain can sign up.
if (user.email.indexOf('@acme.com') === -1) {
throw new functions.auth.HttpsError('invalid-argument', `Unauthorized email "${user.email}"`);
}
});
Niezależnie od tego, czy używasz wiadomości domyślnej czy niestandardowej, funkcja Cloud Functions otacza błąd i zwraca go klientowi jako błąd wewnętrzny. Przykład:
throw new functions.auth.HttpsError('invalid-argument', `Unauthorized email user@evil.com}`);
Aplikacja powinna wykryć błąd i odpowiednio go obsłużyć. Przykład:
JavaScript
// Blocking functions can also be triggered in a multi-tenant context before user creation.
// firebase.auth().tenantId = 'tenant-id-1';
firebase.auth().createUserWithEmailAndPassword('johndoe@example.com', 'password')
.then((result) => {
result.user.getIdTokenResult()
})
.then((idTokenResult) => {
console.log(idTokenResult.claim.admin);
})
.catch((error) => {
if (error.code !== 'auth/internal-error' && error.message.indexOf('Cloud Function') !== -1) {
// Display error.
} else {
// Registration succeeds.
}
});
Modyfikowanie użytkownika
Zamiast blokować rejestrację lub próbę logowania, możesz zezwolić na kontynuowanie operacji, ale zmodyfikować obiekt User
, który jest zapisany w bazie danych Firebase Authentication i zwracany do klienta.
Aby zmodyfikować użytkownika, zwróć z modułu obsługi zdarzeń obiekt zawierający pola do modyfikacji. Możesz zmodyfikować te pola:
displayName
disabled
emailVerified
photoUrl
customClaims
sessionClaims
(tylkobeforeSignIn
)
Z wyjątkiem pola sessionClaims
wszystkie zmodyfikowane pola są zapisywane w bazie danych Firebase Authentication, co oznacza, że są one uwzględniane w tokenie odpowiedzi i pozostają w pamięci między sesjami użytkownika.
Ten przykład pokazuje, jak ustawić domyślną wyświetlaną nazwę:
Node.js
exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
return {
// If no display name is provided, set it to "Guest".
displayName: user.displayName || 'Guest';
};
});
Jeśli zarejestrujesz moduł obsługi zdarzeń zarówno dla beforeCreate
, jak i beforeSignIn
, pamiętaj, że beforeSignIn
jest wykonywane po beforeCreate
. Pola użytkownika zaktualizowane w beforeCreate
są widoczne w beforeSignIn
. Jeśli w obu modułach obsługi zdarzeń ustawisz pole inne niż sessionClaims
, wartość ustawiona w polu beforeSignIn
zastąpi wartość ustawioną w beforeCreate
. Tylko w przypadku sessionClaims
są one propagowane do roszczeń dotyczących tokenów bieżącej sesji, ale nie są przechowywane ani zapisywane w bazie danych.
Jeśli na przykład ustawisz jakiekolwiek wartości sessionClaims
, beforeSignIn
zwróci je wraz z dowolnymi oświadczeniami beforeCreate
, które zostaną scalone. Jeśli po ich scaleniu klucz sessionClaims
pasuje do klucza w customClaims
, pasujący klucz customClaims
zostanie zastąpiony w deklaracji tokenów kluczem sessionClaims
. Jednak nadpisany klucz customClaims
nadal będzie przechowywany w bazie danych na potrzeby przyszłych żądań.
Obsługiwane dane uwierzytelniające i dane OAuth
Do funkcji blokowania możesz przekazywać dane i dane uwierzytelniające OAuth z różnych dostawców tożsamości. W tabeli poniżej znajdziesz informacje o danych logowania i danych obsługiwanych przez poszczególnych dostawców tożsamości:
Dostawca tożsamości | Identyfikator tokena | Token dostępu | Data ważności | Tajny token | Token odświeżania | Żądania logowania |
---|---|---|---|---|---|---|
Tak | Tak | Tak | Nie | Tak | Nie | |
Nie | Tak | Tak | Nie | Nie | Nie | |
Nie | Tak | Nie | Tak | Nie | Nie | |
GitHub | Nie | Tak | Nie | Nie | Nie | Nie |
Microsoft | Tak | Tak | Tak | Nie | Tak | Nie |
Nie | Tak | Tak | Nie | Nie | Nie | |
Yahoo | Tak | Tak | Tak | Nie | Tak | Nie |
Apple | Tak | Tak | Tak | Nie | Tak | Nie |
SAML | Nie | Nie | Nie | Nie | Nie | Tak |
OIDC | Tak | Tak | Tak | Nie | Tak | Tak |
Tokeny odświeżania
Aby użyć tokena odświeżania w funkcji blokującej, musisz najpierw zaznaczyć pole wyboru na stronie Funkcje blokowania w konsoli Firebase.
Żaden dostawca tożsamości nie zwróci tokenów odświeżania podczas logowania się bezpośrednio za pomocą danych logowania OAuth, takich jak token identyfikacyjny lub token dostępu. W tej sytuacji do funkcji blokującej zostaną przekazane te same dane uwierzytelniające OAuth po stronie klienta.
W kolejnych sekcjach opisaliśmy poszczególne typy dostawców tożsamości oraz obsługiwane przez nich dane i uprawnienia.
Dostawcy ogólnej wersji funkcji OIDC
Gdy użytkownik zaloguje się u ogólnego dostawcy OIDC, zostaną przekazane te dane logowania:
- Token tożsamości: jest udostępniany, jeśli wybrano przepływ
id_token
. - Token dostępu: podawany, jeśli wybrano przepływ kodu. Uwaga: proces ten jest obecnie obsługiwany tylko za pomocą interfejsu REST API.
- Token odświeżania: jest dostępny, jeśli wybrano zakres
offline_access
.
Przykład:
const provider = new firebase.auth.OAuthProvider('oidc.my-provider');
provider.addScope('offline_access');
firebase.auth().signInWithPopup(provider);
Gdy użytkownik loguje się w Google, przekazywane są te dane logowania:
- Token identyfikacyjny
- Token dostępu
- Token odświeżania: podawany tylko wtedy, gdy żądane są te parametry niestandardowe:
access_type=offline
prompt=consent
, jeśli użytkownik wyraził wcześniej zgodę i nie poproszono o nowy zakres
Przykład:
const provider = new firebase.auth.GoogleAuthProvider();
provider.setCustomParameters({
'access_type': 'offline',
'prompt': 'consent'
});
firebase.auth().signInWithPopup(provider);
Dowiedz się więcej o tokenach odświeżania Google.
Gdy użytkownik zaloguje się przez Facebooka, zostaną przekazane następujące dane logowania:
- Token dostępu: zwracany jest token dostępu, który można wymienić na inny token dostępu. Dowiedz się więcej o różnych typach tokenów dostępu obsługiwanych przez Facebooka i o tym, jak można je zamienić na tokeny długookresowe.
GitHub
Gdy użytkownik zaloguje się w GitHub, zostaną przekazane te dane logowania:
- Token dostępu: nie wygasa, chyba że zostanie cofnięty.
Microsoft
Gdy użytkownik zaloguje się przez Microsoft, zostaną przekazane te dane logowania:
- Token identyfikacyjny
- Token dostępu
- Token odświeżania: przekazywany do funkcji blokowania, jeśli wybrano zakres
offline_access
.
Przykład:
const provider = new firebase.auth.OAuthProvider('microsoft.com');
provider.addScope('offline_access');
firebase.auth().signInWithPopup(provider);
Yahoo
Gdy użytkownik zaloguje się za pomocą Yahoo, zostaną przekazane te dane logowania bez żadnych parametrów ani zakresów niestandardowych:
- Token identyfikacyjny
- Token dostępu
- Token odświeżania
Gdy użytkownik zaloguje się za pomocą LinkedIn, zostaną przekazane te dane:
- Token dostępu
Apple
Gdy użytkownik loguje się za pomocą Apple, przekazywane są te dane logowania bez żadnych parametrów ani zakresów niestandardowych:
- Token identyfikacyjny
- Token dostępu
- Token odświeżania
Typowe scenariusze
Poniższe przykłady pokazują kilka typowych zastosowań funkcji blokowania:
Zezwalanie na rejestrację tylko z konkretnej domeny
Poniższy przykład pokazuje, jak uniemożliwić użytkownikom, którzy nie należą do domeny example.com
, rejestrowanie się w Twojej aplikacji:
Node.js
exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
if (!user.email || user.email.indexOf('@example.com') === -1) {
throw new functions.auth.HttpsError(
'invalid-argument', `Unauthorized email "${user.email}"`);
}
});
Blokowanie rejestracji użytkowników z niezweryfikowanymi adresami e-mail
Ten przykład pokazuje, jak uniemożliwić użytkownikom z niezweryfikowanymi adresami e-mail rejestrowanie się w aplikacji:
Node.js
exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
if (user.email && !user.emailVerified) {
throw new functions.auth.HttpsError(
'invalid-argument', `Unverified email "${user.email}"`);
}
});
Wymaganie potwierdzenia adresu e-mail podczas rejestracji
Ten przykład pokazuje, jak wymagać od użytkownika potwierdzenia adresu e-mail po rejestracji:
Node.js
exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
const locale = context.locale;
if (user.email && !user.emailVerified) {
// Send custom email verification on sign-up.
return admin.auth().generateEmailVerificationLink(user.email).then((link) => {
return sendCustomVerificationEmail(user.email, link, locale);
});
}
});
exports.beforeSignIn = functions.auth.user().beforeSignIn((user, context) => {
if (user.email && !user.emailVerified) {
throw new functions.auth.HttpsError(
'invalid-argument', `"${user.email}" needs to be verified before access is granted.`);
}
});
traktowanie niektórych e-maili od dostawcy tożsamości jako zweryfikowanych.
Ten przykład pokazuje, jak traktować e-maile użytkowników od określonych dostawców tożsamości jako zweryfikowane:
Node.js
exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
if (user.email && !user.emailVerified && context.eventType.indexOf(':facebook.com') !== -1) {
return {
emailVerified: true,
};
}
});
Blokowanie logowania z określonych adresów IP
Ten przykład pokazuje, jak blokować logowanie z określonych zakresów adresów IP:
Node.js
exports.beforeSignIn = functions.auth.user().beforeSignIn((user, context) => {
if (isSuspiciousIpAddress(context.ipAddress)) {
throw new functions.auth.HttpsError(
'permission-denied', 'Unauthorized access!');
}
});
Ustawianie deklaracji niestandardowych i deklaracji sesji
Poniższy przykład pokazuje, jak ustawić deklaracja niestandardowych i sesji:
Node.js
exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
if (context.credential &&
context.credential.providerId === 'saml.my-provider-id') {
return {
// Employee ID does not change so save in persistent claims (stored in
// Auth DB).
customClaims: {
eid: context.credential.claims.employeeid,
},
// Copy role and groups to token claims. These will not be persisted.
sessionClaims: {
role: context.credential.claims.role,
groups: context.credential.claims.groups,
}
}
}
});
Śledzenie adresów IP w celu monitorowania podejrzanej aktywności
Aby zapobiec kradzieży tokenów, możesz śledzić adres IP, z którego loguje się użytkownik, i porównywać go z adresem IP w kolejnych żądaniach. Jeśli prośba wydaje się podejrzana, np. adresy IP pochodzą z różnych regionów geograficznych, możesz poprosić użytkownika o ponowne zalogowanie się.
Używaj roszczeń sesji, aby śledzić adres IP, z którego użytkownik się loguje:
Node.js
exports.beforeSignIn = functions.auth.user().beforeSignIn((user, context) => { return { sessionClaims: { signInIpAddress: context.ipAddress, }, }; });
Gdy użytkownik próbuje uzyskać dostęp do zasobów, które wymagają uwierzytelniania za pomocą adresu Firebase Authentication, porównaj adres IP w żądaniu z adresem IP użytym do zalogowania:
Node.js
app.post('/getRestrictedData', (req, res) => { // Get the ID token passed. const idToken = req.body.idToken; // Verify the ID token, check if revoked and decode its payload. admin.auth().verifyIdToken(idToken, true).then((claims) => { // Get request IP address const requestIpAddress = req.connection.remoteAddress; // Get sign-in IP address. const signInIpAddress = claims.signInIpAddress; // Check if the request IP address origin is suspicious relative to // the session IP addresses. The current request timestamp and the // auth_time of the ID token can provide additional signals of abuse, // especially if the IP address suddenly changed. If there was a sudden // geographical change in a short period of time, then it will give // stronger signals of possible abuse. if (!isSuspiciousIpAddressChange(signInIpAddress, requestIpAddress)) { // Suspicious IP address change. Require re-authentication. // You can also revoke all user sessions by calling: // admin.auth().revokeRefreshTokens(claims.sub). res.status(401).send({error: 'Unauthorized access. Please login again!'}); } else { // Access is valid. Try to return data. getData(claims).then(data => { res.end(JSON.stringify(data); }, error => { res.status(500).send({ error: 'Server error!' }) }); } }); });
Sprawdzanie zdjęć użytkowników
Ten przykład pokazuje, jak wygładzić zdjęcia profilowe użytkowników:
Node.js
exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
if (user.photoURL) {
return isPhotoAppropriate(user.photoURL)
.then((status) => {
if (!status) {
// Sanitize inappropriate photos by replacing them with guest photos.
// Users could also be blocked from sign-up, disabled, etc.
return {
photoUrl: PLACEHOLDER_GUEST_PHOTO_URL,
};
}
});
});
Więcej informacji o wykrywaniu i czyszczeniu obrazów znajdziesz w dokumentacji Cloud Vision.
Uzyskiwanie dostępu do danych logowania OAuth dostawcy tożsamości użytkownika
Ten przykład pokazuje, jak uzyskać token odświeżania dla użytkownika zalogowanego w Google i użyć go do wywołania interfejsów Google Calendar API. Token odświeżania jest przechowywany na potrzeby dostępu offline.
Node.js
const {OAuth2Client} = require('google-auth-library');
const {google} = require('googleapis');
// ...
// Initialize Google OAuth client.
const keys = require('./oauth2.keys.json');
const oAuth2Client = new OAuth2Client(
keys.web.client_id,
keys.web.client_secret
);
exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
if (context.credential &&
context.credential.providerId === 'google.com') {
// Store the refresh token for later offline use.
// These will only be returned if refresh tokens credentials are included
// (enabled by Cloud console).
return saveUserRefreshToken(
user.uid,
context.credential.refreshToken,
'google.com'
)
.then(() => {
// Blocking the function is not required. The function can resolve while
// this operation continues to run in the background.
return new Promise((resolve, reject) => {
// For this operation to succeed, the appropriate OAuth scope should be requested
// on sign in with Google, client-side. In this case:
// https://www.googleapis.com/auth/calendar
// You can check granted_scopes from within:
// context.additionalUserInfo.profile.granted_scopes (space joined list of scopes).
// Set access token/refresh token.
oAuth2Client.setCredentials({
access_token: context.credential.accessToken,
refresh_token: context.credential.refreshToken,
});
const calendar = google.calendar('v3');
// Setup Onboarding event on user's calendar.
const event = {/** ... */};
calendar.events.insert({
auth: oauth2client,
calendarId: 'primary',
resource: event,
}, (err, event) => {
// Do not fail. This is a best effort approach.
resolve();
});
});
})
}
});
Przerwanie działania reCAPTCHA Enterprise w przypadku działania użytkownika
Ten przykład pokazuje, jak zastąpić werdykt reCAPTCHA Enterprise w przypadku obsługiwanych przepływów danych użytkownika.
Więcej informacji o integrowaniu reCAPTCHA Enterprise z usługą uwierzytelniania Firebase znajdziesz w artykule Włączanie reCAPTCHA Enterprise.
Funkcji blokowania można używać do zezwalania na przepływy danych lub ich blokowania na podstawie niestandardowych czynników, co pozwala zastąpić wynik z reCAPTCHA Enterprise.
Node.js
const functions = require("firebase-functions/v1");
exports.beforesmsv1 = functions.auth.user().beforeSms((context) => {
if (
context.smsType === "SIGN_IN_OR_SIGN_UP" &&
context.additionalUserInfo.phoneNumber.includes('+91')
) {
return {
recaptchaActionOverride: "ALLOW",
};
}
// Allow users to sign in with recaptcha score greater than 0.5
if (event.additionalUserInfo.recaptchaScore > 0.5) {
return {
recaptchaActionOverride: 'ALLOW',
};
}
// Block all others.
return {
recaptchaActionOverride: 'BLOCK',
}
});