Engelleme işlevleri, bir kullanıcının uygulamanıza kaydolup kaydolamayacağını veya uygulamanızda oturum açıp açmayacağını belirleyen özel bir kodu yürütmenize olanak tanır. Örneğin, belirli ölçütleri karşılamayan bir kullanıcının kimliğini doğrulamasını engelleyebilir veya kullanıcının bilgilerini istemci uygulamanıza döndürmeden önce güncelleyebilirsiniz.
Başlamadan önce
Engelleme işlevlerini kullanmak için Firebase projenizi Firebase Authentication with Identity Platform sürümüne yükseltmeniz gerekir. Henüz yükseltme yapmadıysanız önce yükseltme yapın.
Engelleme işlevlerini anlama
Aşağıdaki etkinlikler için engelleme işlevlerini kaydedebilirsiniz:
Kullanıcı oluşturulmadan önce: Yeni bir kullanıcı Firebase Authentication veritabanına kaydedilmeden ve istemci uygulamanıza jeton döndürülmeden önce tetiklenir.
Kullanıcı oturum açmadan önce: Kullanıcının kimlik bilgileri doğrulandıktan sonra ancak Firebase Authentication istemci uygulamanıza kimlik jetonu döndürmeden önce tetiklenir. Uygulamanızda çok öğeli kimlik doğrulama kullanılıyorsa işlev, kullanıcı ikinci öğesini doğruladıktan sonra tetiklenir. Yeni bir kullanıcı oluşturmanın da bu iki etkinliği tetiklediğini unutmayın.
E-posta göndermeden önce (yalnızca Node.js): Bir kullanıcıya e-posta (ör. oturum açma veya şifre sıfırlama e-postası) gönderilmeden önce tetiklenir.
SMS mesajı göndermeden önce (yalnızca Node.js): Çok faktörlü kimlik doğrulama gibi durumlarda, kullanıcıya SMS mesajı gönderilmeden önce tetiklenir.
Engelleme işlevlerini kullanırken aşağıdakileri göz önünde bulundurun:
İşleviniz 7 saniye içinde yanıt vermelidir. 7 saniye sonra Firebase Authentication hata döndürür ve istemci işlemi başarısız olur.
200
dışındaki HTTP yanıt kodları, istemci uygulamalarınıza iletilir. İstemci kodunuzun, işlevinizin döndürebileceği tüm hataları işlediğinden emin olun.İşlevler, kiracı içinde bulunanlar da dahil olmak üzere projenizdeki tüm kullanıcılar için geçerlidir. Firebase Authentication, kullanıcılar hakkında işlevinize bilgi sağlar. Bu bilgiler, kullanıcıların ait olduğu kiracıları da içerir. Böylece, buna göre yanıt verebilirsiniz.
Başka bir kimlik sağlayıcıyı hesaba bağlamak, kayıtlı tüm
beforeUserSignedIn
işlevlerini yeniden tetikler.Anonim ve özel kimlik doğrulama, engelleme işlevlerini tetiklemez.
Engelleme işlevi dağıtma
Özel kodunuzu kullanıcı kimlik doğrulama akışlarına eklemek için engelleme işlevlerini dağıtın. Engelleme işlevleriniz dağıtıldıktan sonra kimlik doğrulama ve kullanıcı oluşturma işlemlerinin başarılı olması için özel kodunuzun başarıyla tamamlanması gerekir.
Engelleme işlevini, diğer işlevleri dağıttığınız şekilde dağıtırsınız. (Ayrıntılar için Cloud Functions Başlangıç sayfasına bakın). Özet olarak:
Hedeflenen etkinliği işleyen bir işlev yazın.
Örneğin, başlamak için kaynağınıza aşağıdaki gibi bir no-op işlevi ekleyebilirsiniz:
Node.js
import { beforeUserCreated, } from "firebase-functions/v2/identity"; export const beforecreated = beforeUserCreated((event) => { // TODO return; });
Python
@identity_fn.before_user_created() def created_noop(event: identity_fn.AuthBlockingEvent) -> identity_fn.BeforeCreateResponse | None: return
Yukarıdaki örnekte özel kimlik doğrulama mantığının uygulanması atlanmıştır. Engelleme işlevlerinizi nasıl uygulayacağınızı öğrenmek için aşağıdaki bölümlere, belirli örnekler için ise Sık karşılaşılan senaryolar'a bakın.
Firebase CLI'yı kullanarak işlevlerinizi dağıtın:
firebase deploy --only functions
Fonksiyonlarınızı her güncellediğinizde yeniden dağıtmanız gerekir.
Kullanıcı ve bağlam bilgilerini alma
Engelleme etkinlikleri, oturum açan kullanıcıyla ilgili bilgileri içeren bir AuthBlockingEvent
nesne sağlar. Bir işlemin devam etmesine izin verilip verilmeyeceğini belirlemek için kodunuzda bu değerleri kullanın.
Nesne aşağıdaki özellikleri içerir:
Ad | Açıklama | Örnek |
---|---|---|
locale |
Uygulama yerel ayarı. Yerel ayarı istemci SDK'sını kullanarak veya REST API'de yerel ayar üstbilgisini ileterek ayarlayabilirsiniz. | fr veya sv-SE |
ipAddress
| Son kullanıcının kayıt yaptığı veya oturum açtığı cihazın IP adresi. | 114.14.200.1 |
userAgent
| Engelleme işlevini tetikleyen kullanıcı aracısı. | Mozilla/5.0 (X11; Linux x86_64) |
eventId
| Etkinliğin benzersiz tanımlayıcısı. | rWsyPtolplG2TBFoOkkgyg |
eventType
|
Etkinlik türü. Bu, etkinlik adı (ör. beforeSignIn veya beforeCreate ) ve kullanılan ilişkili oturum açma yöntemi (ör. Google veya e-posta/şifre) hakkında bilgi sağlar.
|
providers/cloud.auth/eventTypes/user.beforeSignIn:password
|
authType
| Her zaman USER . |
USER
|
resource
| Firebase Authentication projesi veya kiracısı. |
projects/project-id/tenants/tenant-id
|
timestamp
| Etkinliğin tetiklendiği zaman, RFC 3339 dizesi olarak biçimlendirilir. | Tue, 23 Jul 2019 21:10:57 GMT
|
additionalUserInfo
| Kullanıcı hakkında bilgi içeren bir nesne. |
AdditionalUserInfo
|
credential
| Kullanıcının kimlik bilgisiyle ilgili bilgileri içeren bir nesne. |
AuthCredential
|
Kayıt veya oturum açma işlemlerini engelleme
Bir kayıt veya oturum açma girişimini engellemek için işlevinize HttpsError
ekleyin. Örneğin:
Node.js
import { HttpsError } from "firebase-functions/v2/identity";
throw new HttpsError('invalid-argument');
Python
raise https_fn.HttpsError(
code=https_fn.FunctionsErrorCode.INVALID_ARGUMENT)
Ayrıca özel bir hata mesajı da belirtebilirsiniz:
Node.js
throw new HttpsError('permission-denied', 'Unauthorized request origin!');
Python
raise https_fn.HttpsError(
code=https_fn.FunctionsErrorCode.PERMISSION_DENIED,
message="Unauthorized request origin!"
)
Aşağıdaki örnekte, belirli bir alanın dışında olan kullanıcıların uygulamanıza kaydolmasını nasıl engelleyeceğiniz gösterilmektedir:
Node.js
export const beforecreated = beforeUserCreated((event) => {
const user = event.data;
// (If the user is authenticating within a tenant context, the tenant ID can be determined from
// user.tenantId or from event.resource, e.g. 'projects/project-id/tenant/tenant-id-1')
// Only users of a specific domain can sign up.
if (!user?.email?.includes('@acme.com')) {
throw new HttpsError('invalid-argument', "Unauthorized email");
}
});
Python
# Block account creation with any non-acme email address.
@identity_fn.before_user_created()
def validatenewuser(
event: identity_fn.AuthBlockingEvent) -> identity_fn.BeforeCreateResponse | None:
# User data passed in from the CloudEvent.
user = event.data
# Only users of a specific domain can sign up.
if user.email is None or "@acme.com" not in user.email:
# Return None so that Firebase Auth rejects the account creation.
raise https_fn.HttpsError(code=https_fn.FunctionsErrorCode.INVALID_ARGUMENT,
message="Unauthorized email")
Varsayılan veya özel bir mesaj kullanıp kullanmadığınızdan bağımsız olarak, Cloud Functions hatayı sarmalar ve istemciye dahili hata olarak döndürür. Örneğin:
Node.js
throw new HttpsError('invalid-argument', "Unauthorized email");
Python
# Only users of a specific domain can sign up.
if user.email is None or "@acme.com" not in user.email:
# Return None so that Firebase Auth rejects the account creation.
raise https_fn.HttpsError(code=https_fn.FunctionsErrorCode.INVALID_ARGUMENT,
message="Unauthorized email")
Uygulamanız hatayı yakalamalı ve buna göre işlem yapmalıdır. Örneğin:
JavaScript
import { getAuth, createUserWithEmailAndPassword } from 'firebase/auth';
// Blocking functions can also be triggered in a multi-tenant context before user creation.
// firebase.auth().tenantId = 'tenant-id-1';
const auth = getAuth();
try {
const result = await createUserWithEmailAndPassword(auth)
const idTokenResult = await result.user.getIdTokenResult();
console.log(idTokenResult.claim.admin);
} catch(error) {
if (error.code !== 'auth/internal-error' && error.message.indexOf('Cloud Function') !== -1) {
// Display error.
} else {
// Registration succeeds.
}
}
Kullanıcıyı değiştirme
Kayıt veya oturum açma girişimini engellemek yerine işlemin devam etmesine izin verebilirsiniz ancak User
nesnesini değiştirerek Firebase Authentication'nin veritabanına kaydedebilir ve istemciye döndürebilirsiniz.
Bir kullanıcıyı değiştirmek için etkinlik işleyicinizden, değiştirilecek alanları içeren bir nesne döndürün. Aşağıdaki alanları değiştirebilirsiniz:
displayName
disabled
emailVerified
photoUrl
customClaims
sessionClaims
(yalnızcabeforeUserSignedIn
)
sessionClaims
hariç tüm değiştirilen alanlar Firebase Authentication'nin veritabanına kaydedilir. Bu nedenle, yanıt jetonuna dahil edilirler ve kullanıcı oturumları arasında kalıcı olurlar.
Aşağıdaki örnekte, varsayılan görünen adın nasıl ayarlanacağı gösterilmektedir:
Node.js
export const beforecreated = beforeUserCreated((event) => {
return {
// If no display name is provided, set it to "Guest".
displayName: event.data.displayName || 'Guest'
};
});
Python
@identity_fn.before_user_created()
def setdefaultname(event: identity_fn.AuthBlockingEvent) -> identity_fn.BeforeCreateResponse | None:
return identity_fn.BeforeCreateResponse(
# If no display name is provided, set it to "Guest".
display_name=event.data.display_name if event.data.display_name is not None else "Guest")
Hem beforeUserCreated
hem de beforeUserSignedIn
için bir etkinlik işleyici kaydederseniz beforeUserSignedIn
'nin beforeUserCreated
'dan sonra yürütüleceğini unutmayın. beforeUserCreated
içinde güncellenen kullanıcı alanları beforeUserSignedIn
içinde görünür. Her iki etkinlik işleyicide de sessionClaims
dışında bir alan ayarlarsanız beforeUserSignedIn
içinde ayarlanan değer, beforeUserCreated
içinde ayarlanan değerin üzerine yazılır. Yalnızca sessionClaims
için geçerli olan bu bilgiler, mevcut oturumun jeton taleplerine yayılır ancak veritabanında kalıcı hale getirilmez veya depolanmaz.
Örneğin, herhangi bir sessionClaims
ayarlanmışsa beforeUserSignedIn
bunları beforeUserCreated
hak talepleriyle birlikte döndürür ve bunlar birleştirilir. Birleştirildiklerinde, sessionClaims
anahtarı customClaims
içindeki bir anahtarla eşleşirse eşleşen customClaims
, jeton taleplerinde sessionClaims
anahtarıyla üzerine yazılır. Ancak, üzerine yazılan customClaims
anahtarı, gelecekteki istekler için veritabanında kalmaya devam eder.
Desteklenen OAuth kimlik bilgileri ve verileri
Çeşitli kimlik sağlayıcılardan gelen OAuth kimlik bilgilerini ve verilerini engelleme işlevlerine iletebilirsiniz. Aşağıdaki tabloda, her kimlik sağlayıcı için hangi kimlik bilgilerinin ve verilerin desteklendiği gösterilmektedir:
Kimlik Sağlayıcı | Kimlik jetonu | Erişim Jetonu | Son Kullanma Tarihi | Jeton Gizli Anahtarı | Yenileme Jetonu | Oturum açma hak talepleri |
---|---|---|---|---|---|---|
Evet | Evet | Evet | Hayır | Evet | Hayır | |
Hayır | Evet | Evet | Hayır | Hayır | Hayır | |
Hayır | Evet | Hayır | Evet | Hayır | Hayır | |
GitHub | Hayır | Evet | Hayır | Hayır | Hayır | Hayır |
Microsoft | Evet | Evet | Evet | Hayır | Evet | Hayır |
Hayır | Evet | Evet | Hayır | Hayır | Hayır | |
Yahoo | Evet | Evet | Evet | Hayır | Evet | Hayır |
Apple | Evet | Evet | Evet | Hayır | Evet | Hayır |
SAML | Hayır | Hayır | Hayır | Hayır | Hayır | Evet |
OIDC | Evet | Evet | Evet | Hayır | Evet | Evet |
OAuth jetonları
Bir engelleme işlevinde kimlik jetonu, erişim jetonu veya yenileme jetonu kullanmak için önce Firebase konsolunun Engelleme işlevleri sayfasındaki onay kutusunu işaretlemeniz gerekir.
Doğrudan bir OAuth kimlik bilgisiyle (ör. kimlik jetonu veya erişim jetonu) oturum açarken yenileme jetonları hiçbir kimlik sağlayıcı tarafından döndürülmez. Bu durumda, aynı istemci tarafı OAuth kimlik bilgisi engelleme işlevine iletilir.
Aşağıdaki bölümlerde her kimlik sağlayıcı türü ile desteklenen kimlik bilgileri ve veriler açıklanmaktadır.
Genel OIDC sağlayıcıları
Kullanıcı genel bir OIDC sağlayıcısı ile oturum açtığında aşağıdaki kimlik bilgileri iletilir:
- Kimlik jetonu:
id_token
akışı seçilirse sağlanır. - Erişim jetonu: Kod akışı seçilirse sağlanır. Kod akışının şu anda yalnızca REST API üzerinden desteklendiğini unutmayın.
- Yenileme jetonu:
offline_access
kapsamı seçiliyse sağlanır.
Örnek:
const provider = new firebase.auth.OAuthProvider('oidc.my-provider');
provider.addScope('offline_access');
firebase.auth().signInWithPopup(provider);
Kullanıcı Google ile oturum açtığında aşağıdaki kimlik bilgileri iletilir:
- Kimlik jetonu
- Erişim jetonu
- Yenileme jetonu: Yalnızca aşağıdaki özel parametreler istenirse sağlanır:
access_type=offline
prompt=consent
, kullanıcı daha önce izin verdiyse ve yeni kapsam istenmediyse
Örnek:
import { getAuth, signInWithPopup, GoogleAuthProvider } from 'firebase/auth';
const auth = getAuth();
const provider = new GoogleAuthProvider();
provider.setCustomParameters({
'access_type': 'offline',
'prompt': 'consent'
});
signInWithPopup(auth, provider);
Google yenileme jetonları hakkında daha fazla bilgi edinin.
Kullanıcı Facebook ile oturum açtığında aşağıdaki kimlik bilgisi iletilir:
- Erişim jetonu: Başka bir erişim jetonuyla değiştirilebilen bir erişim jetonu döndürülür. Facebook tarafından desteklenen farklı erişim jetonları türleri ve bunları nasıl uzun ömürlü jetonlarla değiştirebileceğiniz hakkında daha fazla bilgi edinin.
GitHub
Kullanıcı GitHub ile oturum açtığında aşağıdaki kimlik bilgisi iletilir:
- Erişim jetonu: İptal edilmediği sürece süresi dolmaz.
Microsoft
Kullanıcı Microsoft ile oturum açtığında aşağıdaki kimlik bilgileri iletilir:
- Kimlik jetonu
- Erişim jetonu
- Yenileme jetonu:
offline_access
kapsamı seçiliyse engelleme işlevine iletilir.
Örnek:
import { getAuth, signInWithPopup, OAuthProvider } from 'firebase/auth';
const auth = getAuth();
const provider = new OAuthProvider('microsoft.com');
provider.addScope('offline_access');
signInWithPopup(auth, provider);
Yahoo
Bir kullanıcı Yahoo ile oturum açtığında aşağıdaki kimlik bilgileri özel parametreler veya kapsamlar olmadan iletilir:
- Kimlik jetonu
- Erişim jetonu
- Yenileme jetonu
Bir kullanıcı LinkedIn ile oturum açtığında aşağıdaki kimlik bilgisi iletilir:
- Erişim jetonu
Apple
Bir kullanıcı Apple ile oturum açtığında aşağıdaki kimlik bilgileri özel parametreler veya kapsamlar olmadan iletilir:
- Kimlik jetonu
- Erişim jetonu
- Yenileme jetonu
Sık karşılaşılan senaryolar
Aşağıdaki örneklerde, engelleme işlevlerinin yaygın kullanım alanlarından bazıları gösterilmektedir:
Yalnızca belirli bir alandan kayda izin verme
Aşağıdaki örnekte, example.com
alanının parçası olmayan kullanıcıların uygulamanıza kaydolmasını nasıl engelleyeceğiniz gösterilmektedir:
Node.js
export const beforecreated = beforeUserCreated((event) => {
const user = event.data;
if (!user?.email?.includes('@example.com')) {
throw new HttpsError(
'invalid-argument', 'Unauthorized email');
}
});
Python
@identity_fn.before_user_created()
def validatenewuser(
event: identity_fn.AuthBlockingEvent,
) -> identity_fn.BeforeCreateResponse | None:
# User data passed in from the CloudEvent.
user = event.data
# Only users of a specific domain can sign up.
if user.email is None or "@example.com" not in user.email:
# Return None so that Firebase Auth rejects the account creation.
raise https_fn.HttpsError(
code=https_fn.FunctionsErrorCode.INVALID_ARGUMENT,
message="Unauthorized email",
)
Doğrulanmamış e-posta adresleri olan kullanıcıların kaydolmasını engelleme
Aşağıdaki örnekte, doğrulanmamış e-posta adreslerine sahip kullanıcıların uygulamanıza kaydolmasını nasıl engelleyeceğiniz gösterilmektedir:
Node.js
export const beforecreated = beforeUserCreated((event) => {
const user = event.data;
if (user.email && !user.emailVerified) {
throw new HttpsError(
'invalid-argument', 'Unverified email');
}
});
Python
@identity_fn.before_user_created()
def requireverified(
event: identity_fn.AuthBlockingEvent) -> identity_fn.BeforeCreateResponse | None:
if event.data.email is not None and not event.data.email_verified:
raise https_fn.HttpsError(code=https_fn.FunctionsErrorCode.INVALID_ARGUMENT,
message="You must register using a trusted provider.")
Belirli kimlik sağlayıcı e-postalarını doğrulanmış olarak ele alma
Aşağıdaki örnekte, belirli kimlik sağlayıcılarından gelen kullanıcı e-postalarının nasıl doğrulanmış olarak ele alınacağı gösterilmektedir:
Node.js
export const beforecreated = beforeUserCreated((event) => {
const user = event.data;
if (user.email && !user.emailVerified && event.eventType.includes(':facebook.com')) {
return {
emailVerified: true,
};
}
});
Python
@identity_fn.before_user_created()
def markverified(event: identity_fn.AuthBlockingEvent) -> identity_fn.BeforeCreateResponse | None:
if event.data.email is not None and "@facebook.com" in event.data.email:
return identity_fn.BeforeSignInResponse(email_verified=True)
Belirli IP adreslerinden oturum açmayı engelleme
Aşağıdaki örnekte, belirli IP adresi aralıklarından oturum açma işlemlerinin nasıl engelleneceği gösterilmektedir:
Node.js
export const beforesignedin = beforeUserSignedIn((event) => {
if (isSuspiciousIpAddress(event.ipAddress)) {
throw new HttpsError(
'permission-denied', 'Unauthorized access!');
}
});
Python
@identity_fn.before_user_signed_in()
def ipban(event: identity_fn.AuthBlockingEvent) -> identity_fn.BeforeSignInResponse | None:
if is_suspicious(event.ip_address):
raise https_fn.HttpsError(code=https_fn.FunctionsErrorCode.PERMISSION_DENIED,
message="IP banned.")
Özel ve oturum taleplerini ayarlama
Aşağıdaki örnekte, özel ve oturum taleplerinin nasıl ayarlanacağı gösterilmektedir:
Node.js
export const beforecreated = beforeUserCreated((event) => {
if (event.credential &&
event.credential.claims &&
event.credential.providerId === "saml.my-provider-id") {
return {
// Employee ID does not change so save in persistent claims (stored in
// Auth DB).
customClaims: {
eid: event.credential.claims.employeeid,
},
};
}
});
export const beforesignin = beforeUserSignedIn((event) => {
if (event.credential &&
event.credential.claims &&
event.credential.providerId === "saml.my-provider-id") {
return {
// Copy role and groups to token claims. These will not be persisted.
sessionClaims: {
role: event.credential.claims.role,
groups: event.credential.claims.groups,
},
};
}
});
Python
@identity_fn.before_user_created()
def setemployeeid(event: identity_fn.AuthBlockingEvent) -> identity_fn.BeforeCreateResponse | None:
if (event.credential is not None and event.credential.claims is not None and
event.credential.provider_id == "saml.my-provider-id"):
return identity_fn.BeforeCreateResponse(
custom_claims={"eid": event.credential.claims["employeeid"]})
@identity_fn.before_user_signed_in()
def copyclaimstosession(
event: identity_fn.AuthBlockingEvent) -> identity_fn.BeforeSignInResponse | None:
if (event.credential is not None and event.credential.claims is not None and
event.credential.provider_id == "saml.my-provider-id"):
return identity_fn.BeforeSignInResponse(session_claims={
"role": event.credential.claims["role"],
"groups": event.credential.claims["groups"]
})
Şüpheli etkinliği izlemek için IP adreslerini takip etme
Kullanıcının oturum açtığı IP adresini izleyip sonraki isteklerdeki IP adresiyle karşılaştırarak jeton hırsızlığını önleyebilirsiniz. İstek şüpheli görünüyorsa (ör. IP'ler farklı coğrafi bölgelerden geliyorsa) kullanıcıdan tekrar oturum açmasını isteyebilirsiniz.
Kullanıcının oturum açtığı IP adresini izlemek için oturum taleplerini kullanın:
Node.js
export const beforesignedin = beforeUserSignedIn((event) => { return { sessionClaims: { signInIpAddress: event.ipAddress, }, }; });
Python
@identity_fn.before_user_signed_in() def logip(event: identity_fn.AuthBlockingEvent) -> identity_fn.BeforeSignInResponse | None: return identity_fn.BeforeSignInResponse(session_claims={"signInIpAddress": event.ip_address})
Bir kullanıcı, Firebase Authentication ile kimlik doğrulama gerektiren kaynaklara erişmeye çalıştığında, istekteki IP adresini oturum açmak için kullanılan IP ile karşılaştırın:
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!' }) }); } }); });
Python
from firebase_admin import auth, initialize_app import flask initialize_app() flask_app = flask.Flask(__name__) @flask_app.post() def get_restricted_data(req: flask.Request): # Get the ID token passed. id_token = req.json().get("idToken") # Verify the ID token, check if revoked, and decode its payload. try: claims = auth.verify_id_token(id_token, check_revoked=True) except: return flask.Response(status=500) # Get request IP address. request_ip = req.remote_addr # Get sign-in IP address. signin_ip = 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 is_suspicious_change(signin_ip, request_ip): # Suspicious IP address change. Require re-authentication. # You can also revoke all user sessions by calling: # auth.revoke_refresh_tokens(claims["sub"]) return flask.Response(status=401, response="Unauthorized access. Sign in again!") else: # Access is valid. Try to return data. return data_from_claims(claims)
Kullanıcı fotoğraflarını inceleme
Aşağıdaki örnekte, kullanıcıların profil fotoğraflarının nasıl temizleneceği gösterilmektedir:
Node.js
export const beforecreated = beforeUserCreated((event) => {
const user = event.data;
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,
};
}
});
});
Python
@identity_fn.before_user_created()
def sanitizeprofilephoto(
event: identity_fn.AuthBlockingEvent) -> identity_fn.BeforeCreateResponse | None:
if event.data.photo_url is not None:
score = analyze_photo_with_ml(event.data.photo_url)
if score > THRESHOLD:
return identity_fn.BeforeCreateResponse(photo_url=PLACEHOLDER_URL)
Görüntüleri algılama ve temizleme hakkında daha fazla bilgi edinmek için Cloud Vision belgelerine bakın.
Kullanıcının kimlik sağlayıcısı OAuth kimlik bilgilerine erişme
Aşağıdaki örnekte, Google ile oturum açan bir kullanıcı için yenileme jetonunun nasıl alınacağı ve Google Takvim API'lerini çağırmak için nasıl kullanılacağı gösterilmektedir. Yenileme jetonu, çevrimdışı erişim için saklanır.
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
);
export const beforecreated = beforeUserCreated((event) => {
const user = event.data;
if (event.credential &&
event.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,
event.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:
// event.additionalUserInfo.profile.granted_scopes (space joined list of scopes).
// Set access token/refresh token.
oAuth2Client.setCredentials({
access_token: event.credential.accessToken,
refresh_token: event.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();
});
});
})
}
});
Python
@identity_fn.before_user_created()
def savegoogletoken(
event: identity_fn.AuthBlockingEvent) -> identity_fn.BeforeCreateResponse | None:
"""During sign-up, save the Google OAuth2 access token and queue up a task
to schedule an onboarding session on the user's Google Calendar.
You will only get an access token if you enabled it in your project's blocking
functions settings in the Firebase console:
https://console.firebase.google.com/project/_/authentication/settings
"""
if event.credential is not None and event.credential.provider_id == "google.com":
print(f"Signed in with {event.credential.provider_id}. Saving access token.")
firestore_client: google.cloud.firestore.Client = firestore.client()
doc_ref = firestore_client.collection("user_info").document(event.data.uid)
doc_ref.set({"calendar_access_token": event.credential.access_token}, merge=True)
tasks_client = google.cloud.tasks_v2.CloudTasksClient()
task_queue = tasks_client.queue_path(params.PROJECT_ID.value,
options.SupportedRegion.US_CENTRAL1,
"scheduleonboarding")
target_uri = get_function_url("scheduleonboarding")
calendar_task = google.cloud.tasks_v2.Task(http_request={
"http_method": google.cloud.tasks_v2.HttpMethod.POST,
"url": target_uri,
"headers": {
"Content-type": "application/json"
},
"body": json.dumps({
"data": {
"uid": event.data.uid
}
}).encode()
},
schedule_time=datetime.now() +
timedelta(minutes=1))
tasks_client.create_task(parent=task_queue, task=calendar_task)
Kullanıcı işlemi için reCAPTCHA Enterprise kararını geçersiz kılma
Aşağıdaki örnekte, desteklenen kullanıcı akışları için reCAPTCHA Enterprise kararının nasıl geçersiz kılınacağı gösterilmektedir.
reCAPTCHA Enterprise'ı Firebase Authentication ile entegre etme hakkında daha fazla bilgi edinmek için reCAPTCHA Enterprise'ı etkinleştirme başlıklı makaleyi inceleyin.
Engelleme işlevleri, akışlara özel faktörlere göre izin vermek veya akışları engellemek için kullanılabilir. Böylece, reCAPTCHA Enterprise tarafından sağlanan sonuç geçersiz kılınır.
Node.js
const { beforeSmsSent } = require("firebase-functions/v2/identity");
exports.beforesmssentv2 = beforeSmsSent((event) => {
if (
event.smsType === "SIGN_IN_OR_SIGN_UP" &&
event.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',
}
});