ब्लॉक करने वाले फ़ंक्शन की मदद से, Firebase से पुष्टि करने की सुविधा को बेहतर बनाएं


ब्लॉक करने वाले फ़ंक्शन की मदद से, कस्टम कोड लागू किया जा सकता है. यह आपके ऐप्लिकेशन में किसी उपयोगकर्ता के रजिस्टर करने या साइन इन करने के नतीजे में बदलाव करता है. उदाहरण के लिए, अगर कोई उपयोगकर्ता तय की गई शर्तों को पूरा नहीं करता है, तो उसे पुष्टि करने से रोका जा सकता है. इसके अलावा, क्लाइंट ऐप्लिकेशन पर वापस जाने से पहले उपयोगकर्ता की जानकारी को अपडेट किया जा सकता है.

वेब कंटेनर इंस्टॉल करने से पहले

ब्लॉक करने वाले फ़ंक्शन का इस्तेमाल करने के लिए, आपको अपने Firebase प्रोजेक्ट को Identity Platform की मदद से, Firebase से पुष्टि करने की सुविधा पर अपग्रेड करना होगा. अगर आपने अभी तक अपग्रेड नहीं किया है, तो पहले यह काम करें.

ब्लॉक करने वाले फ़ंक्शन को समझना

दो इवेंट के लिए, ब्लॉक करने वाले फ़ंक्शन रजिस्टर किए जा सकते हैं:

  • beforeCreate: यह ट्रिगर, नए उपयोगकर्ता को Firebase से पुष्टि करने वाले डेटाबेस में सेव करने से पहले और आपके क्लाइंट ऐप्लिकेशन पर टोकन के वापस आने से पहले ट्रिगर होता है.

  • beforeSignIn: यह तब ट्रिगर होता है, जब उपयोगकर्ता के क्रेडेंशियल की पुष्टि हो जाती है. हालांकि, Firebase से पुष्टि करने से पहले, आपके क्लाइंट ऐप्लिकेशन को आईडी टोकन वापस मिल जाता है. अगर आपका ऐप्लिकेशन बहु-स्तरीय पुष्टि (MFA) की सुविधा का इस्तेमाल करता है, तो यह फ़ंक्शन, उपयोगकर्ता के दूसरे चरण की पुष्टि करने के बाद ट्रिगर हो जाता है. ध्यान दें कि नया उपयोगकर्ता बनाने से, beforeCreate के साथ-साथ beforeSignIn भी ट्रिगर होता है.

ब्लॉक करने वाले फ़ंक्शन का इस्तेमाल करते समय इन बातों का ध्यान रखें:

  • फ़ंक्शन को सात सेकंड के अंदर जवाब देना होगा. सात सेकंड के बाद, Firebase से पुष्टि करने की प्रोसेस में गड़बड़ी का मैसेज दिखता है और क्लाइंट की कार्रवाई फ़ेल हो जाती है.

  • 200 के अलावा, अन्य एचटीटीपी रिस्पॉन्स कोड आपके क्लाइंट ऐप्लिकेशन को पास किए जाते हैं. पक्का करें कि आपका क्लाइंट कोड ऐसी सभी गड़बड़ियों को हैंडल करता हो जो आपके फ़ंक्शन को दिखा सकती हैं.

  • ये फ़ंक्शन आपके प्रोजेक्ट के सभी उपयोगकर्ताओं पर लागू होते हैं. इनमें टेनेंट में मौजूद सभी उपयोगकर्ता भी शामिल हैं. Firebase से पुष्टि करने की सुविधा से, आपके फ़ंक्शन के उपयोगकर्ताओं के बारे में जानकारी मिलती है. इसमें किसी भी किरायेदार की जानकारी शामिल होती है, ताकि आप उसी हिसाब से जवाब दे सकें.

  • किसी खाते से किसी दूसरे आइडेंटिटी प्रोवाइडर को लिंक करने पर, रजिस्टर किए गए कोई भी beforeSignIn फ़ंक्शन फिर से ट्रिगर होते हैं.

  • पहचान छिपाकर और अपने हिसाब से पुष्टि करने की सुविधा से, ब्लॉक करने वाले फ़ंक्शन ट्रिगर नहीं होते.

ब्लॉक करने वाला फ़ंक्शन डिप्लॉय करना

यूज़र ऑथेंटिकेशन फ़्लो में अपना कस्टम कोड डालने के लिए, ब्लॉक करने वाले फ़ंक्शन डिप्लॉय करें. ब्लॉक करने वाले फ़ंक्शन लागू होने के बाद, यह ज़रूरी है कि पुष्टि करने और उपयोगकर्ता बनाने के लिए, आपका कस्टम कोड पूरी तरह से भरें.

ब्लॉक करने वाले फ़ंक्शन को ठीक वैसे ही डिप्लॉय किया जा सकता है जैसे किसी फ़ंक्शन को डिप्लॉय किया जाता है. ज़्यादा जानकारी के लिए, Cloud Functions शुरू करने का तरीका देखें. संक्षेप में:

  1. ऐसे Cloud Functions लिखें जो beforeCreate इवेंट, beforeSignIn इवेंट या दोनों को मैनेज करते हों.

    उदाहरण के लिए, शुरू करने के लिए, index.js में ये नो-ऑप फ़ंक्शन जोड़े जा सकते हैं:

    const functions = require('firebase-functions');
    
    exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
      // TODO
    });
    
    exports.beforeSignIn = functions.auth.user().beforeSignIn((user, context) => {
      // TODO
    });
    

    ऊपर दिए गए उदाहरणों में, कस्टम पुष्टि करने वाले लॉजिक को लागू नहीं किया गया है. ब्लॉक करने वाले फ़ंक्शन को लागू करने का तरीका और कुछ खास उदाहरणों के लिए, सामान्य स्थितियों के बारे में जानने के लिए, नीचे दिए गए सेक्शन देखें.

  2. Firebase सीएलआई का इस्तेमाल करके अपने फ़ंक्शन डिप्लॉय करें:

    firebase deploy --only functions
    

    हर बार अपने फ़ंक्शन को अपडेट करने पर, आपको उन्हें फिर से डिप्लॉय करना होगा.

उपयोगकर्ता और कॉन्टेक्स्ट की जानकारी हासिल करना

beforeSignIn और beforeCreate इवेंट, User और EventContext ऑब्जेक्ट देते हैं. इनमें उपयोगकर्ता के साइन इन करने के बारे में जानकारी होती है. अपने कोड में इन वैल्यू का इस्तेमाल करके यह तय करें कि किसी कार्रवाई को जारी रखना है या नहीं.

User ऑब्जेक्ट पर उपलब्ध प्रॉपर्टी की सूची देखने के लिए, UserRecord एपीआई का रेफ़रंस देखें.

EventContext ऑब्जेक्ट में ये प्रॉपर्टी शामिल हैं:

नाम जानकारी उदाहरण
locale ऐप्लिकेशन की स्थान-भाषा. क्लाइंट SDK टूल का इस्तेमाल करके या REST API में स्थान-भाषा हेडर पास करके, स्थान-भाषा को सेट किया जा सकता है. fr या sv-SE
ipAddress उस डिवाइस का आईपी पता जिसे असली उपयोगकर्ता रजिस्टर कर रहा है या जिससे साइन इन कर रहा है. 114.14.200.1
userAgent ब्लॉक करने वाले फ़ंक्शन को ट्रिगर करने वाला उपयोगकर्ता एजेंट. Mozilla/5.0 (X11; Linux x86_64)
eventId इवेंट का यूनीक आइडेंटिफ़ायर. rWsyPtolplG2TBFoOkkgyg
eventType इवेंट टाइप. इससे इवेंट के नाम, जैसे कि beforeSignIn या beforeCreate के बारे में जानकारी मिलती है. साथ ही, इससे साइन-इन करने के लिए, Google खाते या ईमेल/पासवर्ड जैसे तरीके की जानकारी भी मिलती है. providers/cloud.auth/eventTypes/user.beforeSignIn:password
authType हमेशा USER. USER
resource Firebase से पुष्टि करने का प्रोजेक्ट या किरायेदार (टेनेंट). projects/project-id/tenants/tenant-id
timestamp इवेंट के ट्रिगर होने का समय, जो RFC 3339 स्ट्रिंग के तौर पर फ़ॉर्मैट किया गया है. Tue, 23 Jul 2019 21:10:57 GMT
additionalUserInfo एक ऑब्जेक्ट जिसमें उपयोगकर्ता के बारे में जानकारी होती है. AdditionalUserInfo
credential एक ऑब्जेक्ट, जिसमें उपयोगकर्ता के क्रेडेंशियल की जानकारी होती है. AuthCredential

रजिस्ट्रेशन या साइन-इन करने से रोकना

किसी रजिस्ट्रेशन या साइन इन की कोशिश को ब्लॉक करने के लिए, अपने फ़ंक्शन में HttpsError डालें. उदाहरण के लिए:

Node.js के लिए

throw new functions.auth.HttpsError('permission-denied');

इस टेबल में उन गड़बड़ियों की सूची दी गई है जो आपको दिख सकती हैं. साथ ही, उनके डिफ़ॉल्ट गड़बड़ी वाले मैसेज की सूची भी दी गई है:

नाम कोड मैसेज
invalid-argument 400 क्लाइंट ने एक अमान्य तर्क बताया.
failed-precondition 400 सिस्टम की मौजूदा स्थिति में अनुरोध पूरा नहीं किया जा सकता.
out-of-range 400 क्लाइंट ने एक अमान्य सीमा बताई.
unauthenticated 401 OAuth टोकन मौजूद नहीं है, अमान्य है या इसकी समयसीमा खत्म हो चुकी है.
permission-denied 403 क्लाइंट के पास ज़रूरी अनुमति नहीं है.
not-found 404 बताया गया संसाधन नहीं मिला.
aborted 409 कॉनकरंसी कॉन्फ़्लिक्ट, जैसे कि रीड-इन-राइट विरोधाभास.
already-exists 409 क्लाइंट ने जिस संसाधन को बनाने की कोशिश की, वह पहले से मौजूद है.
resource-exhausted 429 संसाधन की सीमा खत्म हो गई है या अनुरोध संख्या की सीमा तक पहुंचने वाले हैं.
cancelled 499 क्लाइंट ने अनुरोध रद्द कर दिया.
data-loss 500 डेटा को वापस नहीं पाया जा सकता या डेटा खराब हो गया.
unknown 500 सर्वर में अज्ञात गड़बड़ी.
internal 500 सर्वर में गड़बड़ी.
not-implemented 501 सर्वर ने एपीआई तरीका लागू नहीं किया.
unavailable 503 सेवा उपलब्ध नहीं है.
deadline-exceeded 504 अनुरोध का समय खत्म हो गया.

आपके पास गड़बड़ी वाला कोई कस्टम मैसेज दिखाने का विकल्प भी है:

Node.js के लिए

throw new functions.auth.HttpsError('permission-denied', 'Unauthorized request origin!');

नीचे दिए गए उदाहरण में, उन उपयोगकर्ताओं को आपका ऐप्लिकेशन रजिस्टर करने से रोकने का तरीका बताया गया है जो किसी खास डोमेन में नहीं हैं:

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}"`);
  }
});

आप चाहे डिफ़ॉल्ट मैसेज का इस्तेमाल करें या कस्टम मैसेज का, Cloud Functions ही गड़बड़ी को रैप करता है और उसे क्लाइंट को इंटरनल गड़बड़ी के तौर पर भेजता है. उदाहरण के लिए:

throw new functions.auth.HttpsError('invalid-argument', `Unauthorized email user@evil.com}`);

आपके ऐप्लिकेशन को गड़बड़ी पकड़नी चाहिए और उसे उसी हिसाब से हैंडल करना चाहिए. उदाहरण के लिए:

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

उपयोगकर्ता में बदलाव करना

रजिस्ट्रेशन या साइन-इन की कोशिश को ब्लॉक करने के बजाय, कार्रवाई को जारी रखने की अनुमति दी जा सकती है. हालांकि, आपके पास Firebase से पुष्टि करने के डेटाबेस में सेव किए गए User ऑब्जेक्ट में बदलाव करने का विकल्प होता है, जो कि क्लाइंट को वापस मिल जाता है.

उपयोगकर्ता में बदलाव करने के लिए, अपने इवेंट हैंडलर से एक ऑब्जेक्ट दिखाएं, जिसमें बदलाव करने के लिए फ़ील्ड मौजूद हैं. इन फ़ील्ड में बदलाव किया जा सकता है:

  • displayName
  • disabled
  • emailVerified
  • photoUrl
  • customClaims
  • sessionClaims (सिर्फ़ beforeSignIn)

sessionClaims को छोड़कर, बदलाव किए गए सभी फ़ील्ड Firebase से पुष्टि करने वाले डेटाबेस में सेव किए जाते हैं. इसका मतलब है कि वे रिस्पॉन्स टोकन में शामिल होते हैं और उपयोगकर्ता के सेशन के बीच बने रहते हैं.

नीचे दिए गए उदाहरण में, डिफ़ॉल्ट डिसप्ले नेम सेट करने का तरीका बताया गया है:

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';
  };
});

अगर आपने beforeCreate और beforeSignIn, दोनों के लिए कोई इवेंट हैंडलर रजिस्टर किया है, तो ध्यान दें कि beforeSignIn, beforeCreate के बाद काम करता है. beforeCreate में अपडेट किए गए उपयोगकर्ता फ़ील्ड beforeSignIn में दिखते हैं. अगर आपने दोनों इवेंट हैंडलर में sessionClaims के अलावा कोई दूसरा फ़ील्ड सेट किया है, तो beforeSignIn में सेट की गई वैल्यू, beforeCreate में सेट की गई वैल्यू को ओवरराइट कर देती है. सिर्फ़ sessionClaims के लिए, उन्हें मौजूदा सेशन के टोकन दावों में लागू किया जाता है. हालांकि, वे न तो बने रहते हैं और न ही डेटाबेस में सेव रहते हैं.

उदाहरण के लिए, अगर कोई sessionClaims सेट है, तो beforeSignIn उन्हें beforeCreate दावों के साथ दिखाएगा. साथ ही, उन्हें मर्ज कर दिया जाएगा. मर्ज किए जाने के बाद, अगर sessionClaims कुंजी, customClaims में मौजूद कुंजी से मेल खाती है, तो sessionClaims कुंजी की मदद से, टोकन दावों में customClaims को ओवरराइट कर दिया जाएगा. हालांकि, ओवरविफ़्ट की गई customClaims कुंजी, आने वाले समय में किए जाने वाले अनुरोधों के लिए डेटाबेस में अब भी सेव रहेगी.

इस्तेमाल किए जा सकने वाले OAuth क्रेडेंशियल और डेटा

आपके पास OAuth क्रेडेंशियल और डेटा को, पहचान देने वाली अलग-अलग कंपनियों के फ़ंक्शन को ब्लॉक करने के लिए पास करने का विकल्प होता है. इस टेबल में बताया गया है कि हर आइडेंटिटी प्रोवाइडर के लिए, कौनसे क्रेडेंशियल और डेटा का इस्तेमाल किया जाता है:

पहचान देने वाली सेवा आईडी टोकन ऐक्सेस टोकन समाप्ति‍ समय टोकन सीक्रेट रीफ़्रेश टोकन साइन-इन दावे
Google हां हां हां नहीं हां नहीं
Facebook नहीं हां हां नहीं नहीं नहीं
Twitter नहीं हां नहीं हां नहीं नहीं
GitHub नहीं हां नहीं नहीं नहीं नहीं
Microsoft हां हां हां नहीं हां नहीं
LinkedIn नहीं हां हां नहीं नहीं नहीं
Yahoo हां हां हां नहीं हां नहीं
Apple हां हां हां नहीं हां नहीं
एसएएमएल नहीं नहीं नहीं नहीं नहीं हां
OIDC हां हां हां नहीं हां हां

टोकन रीफ़्रेश करें

ब्लॉक करने के फ़ंक्शन में रीफ़्रेश टोकन का इस्तेमाल करने के लिए, सबसे पहले आपको Firebase कंसोल के फ़ंक्शन ब्लॉक करने वाले पेज पर चेकबॉक्स चुनना होगा.

आईडी टोकन या ऐक्सेस टोकन जैसे OAuth क्रेडेंशियल से सीधे साइन इन करने पर, पहचान देने वाली कोई भी कंपनी रीफ़्रेश टोकन नहीं देगी. इस स्थिति में, ब्लॉक करने वाले फ़ंक्शन को एक ही क्लाइंट-साइड OAuth क्रेडेंशियल भेजा जाएगा.

यहां दिए गए सेक्शन में, हर तरह के आइडेंटिटी प्रोवाइडर की जानकारी दी गई है. साथ ही, उनके साथ काम करने वाले क्रेडेंशियल और डेटा के बारे में भी बताया गया है.

जेनरिक OIDC प्रोवाइडर

जब कोई उपयोगकर्ता OIDC की सेवा देने वाली जेनरिक कंपनी में साइन इन करता है, तो ये क्रेडेंशियल पास किए जाएंगे:

  • आईडी टोकन: यह सिर्फ़ तब दिया जाता है, जब id_token फ़्लो को चुना गया हो.
  • ऐक्सेस टोकन: यह विकल्प तब दिया जाता है, जब कोड फ़्लो चुना गया हो. ध्यान दें कि फ़िलहाल कोड फ़्लो सिर्फ़ REST API के ज़रिए काम करता है.
  • रीफ़्रेश टोकन: यह तब दिया जाता है, जब offline_access स्कोप को चुना गया हो.

उदाहरण:

const provider = new firebase.auth.OAuthProvider('oidc.my-provider');
provider.addScope('offline_access');
firebase.auth().signInWithPopup(provider);

Google

जब कोई उपयोगकर्ता Google से साइन इन करता है, तो ये क्रेडेंशियल पास किए जाएंगे:

  • आईडी टोकन
  • ऐक्सेस टोकन
  • रीफ़्रेश टोकन: सिर्फ़ तब दिया जाता है, जब नीचे दिए गए कस्टम पैरामीटर का अनुरोध किया गया हो:
    • access_type=offline
    • prompt=consent, अगर उपयोगकर्ता ने पहले सहमति दी थी और किसी नए दायरे का अनुरोध नहीं किया था

उदाहरण:

const provider = new firebase.auth.GoogleAuthProvider();
provider.setCustomParameters({
  'access_type': 'offline',
  'prompt': 'consent'
});
firebase.auth().signInWithPopup(provider);

Google रीफ़्रेश टोकन के बारे में ज़्यादा जानें.

Facebook

जब कोई उपयोगकर्ता Facebook से साइन इन करता है, तो यह क्रेडेंशियल पास किया जाता है:

  • ऐक्सेस टोकन: एक ऐक्सेस टोकन मिलता है, जिसे किसी दूसरे ऐक्सेस टोकन से बदला जा सकता है. Facebook के साथ काम करने वाले अलग-अलग तरह के ऐक्सेस टोकन के बारे में ज़्यादा जानें. साथ ही, यह भी जानें कि इन टोकन को लंबे समय तक चलने वाले टोकन के लिए कैसे शेयर किया जा सकता है.

GitHub

जब कोई उपयोगकर्ता GitHub से साइन इन करता है, तो यह क्रेडेंशियल पास किया जाएगा:

  • ऐक्सेस टोकन: इसकी समयसीमा तब तक खत्म नहीं होती, जब तक इसे रद्द नहीं किया जाता.

Microsoft

जब कोई उपयोगकर्ता Microsoft से साइन इन करता है, तो ये क्रेडेंशियल पास किए जाते हैं:

  • आईडी टोकन
  • ऐक्सेस टोकन
  • रीफ़्रेश टोकन: offline_access स्कोप को चुने जाने पर, ब्लॉक करने वाले फ़ंक्शन में पास किया जाता है.

उदाहरण:

const provider = new firebase.auth.OAuthProvider('microsoft.com');
provider.addScope('offline_access');
firebase.auth().signInWithPopup(provider);

Yahoo

जब कोई उपयोगकर्ता Yahoo से साइन इन करता है, तो किसी भी कस्टम पैरामीटर या स्कोप के बिना ये क्रेडेंशियल पास किए जाएंगे:

  • आईडी टोकन
  • ऐक्सेस टोकन
  • रीफ़्रेश टोकन

LinkedIn

जब कोई उपयोगकर्ता LinkedIn से साइन इन करता है, तो यह क्रेडेंशियल पास किया जाता है:

  • ऐक्सेस टोकन

Apple

जब कोई उपयोगकर्ता Apple से साइन इन करता है, तो नीचे दिए गए क्रेडेंशियल, किसी भी कस्टम पैरामीटर या स्कोप के बिना पास किए जाएंगे:

  • आईडी टोकन
  • ऐक्सेस टोकन
  • रीफ़्रेश टोकन

आम तौर पर सामने आने वाली स्थितियां

यहां दिए गए उदाहरणों में, ब्लॉक करने वाले फ़ंक्शन के इस्तेमाल के कुछ सामान्य उदाहरण दिए गए हैं:

सिर्फ़ किसी खास डोमेन से रजिस्ट्रेशन की अनुमति देना

यहां दिए गए उदाहरण में, उन उपयोगकर्ताओं को आपके ऐप्लिकेशन के साथ रजिस्टर होने से रोकने का तरीका बताया गया है जो example.com डोमेन का हिस्सा नहीं हैं:

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}"`);
  }
});

उन उपयोगकर्ताओं को रजिस्टर करने से रोकना जिनकी पुष्टि नहीं हुई है

यहां दिए गए उदाहरण में, ऐसे उपयोगकर्ताओं को आपके ऐप्लिकेशन के साथ रजिस्टर होने से रोकने का तरीका बताया गया है जिनके ईमेल की पुष्टि नहीं हुई है:

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}"`);
  }
});

रजिस्ट्रेशन के लिए ईमेल पते की पुष्टि करना

यहां दिए गए उदाहरण में बताया गया है कि रजिस्टर करने के बाद, उपयोगकर्ता से अपने ईमेल पते की पुष्टि करने के लिए कैसे कहा जा सकता है:

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.`);
  }
});

पहचान देने वाली सेवा के कुछ ईमेल को 'पुष्टि हो चुकी है' के तौर पर पेश करना

नीचे दिया गया उदाहरण यह दिखाता है कि पहचान देने वाली कुछ खास कंपनियों से मिले उपयोगकर्ता ईमेल को 'पुष्टि हो चुकी है' के तौर पर कैसे देखें:

Node.js के लिए

exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
  if (user.email && !user.emailVerified && context.eventType.indexOf(':facebook.com') !== -1) {
    return {
      emailVerified: true,
    };
  }
});

कुछ खास आईपी पतों से साइन इन करने की सुविधा को ब्लॉक करना

कुछ खास तरह के आईपी पतों से साइन-इन करने की सुविधा को कैसे ब्लॉक किया जाता है, इसका उदाहरण नीचे दिया गया है:

Node.js के लिए

exports.beforeSignIn = functions.auth.user().beforeSignIn((user, context) => {
  if (isSuspiciousIpAddress(context.ipAddress)) {
    throw new functions.auth.HttpsError(
      'permission-denied', 'Unauthorized access!');
  }
});

कस्टम और सेशन के दावे सेट करना

यहां दिए गए उदाहरण में, कस्टम और सेशन के दावे को सेट करने का तरीका बताया गया है:

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,
      }
    }
  }
});

संदिग्ध गतिविधि पर नज़र रखने के लिए आईपी पतों को ट्रैक करना

किसी उपयोगकर्ता ने जिस आईपी पते से साइन इन किया है उसे ट्रैक करके, टोकन को चोरी होने से रोका जा सकता है. साथ ही, बाद में किए जाने वाले अनुरोधों के लिए उसकी तुलना आईपी पते से की जा सकती है. अगर अनुरोध संदिग्ध लगता है, तो उपयोगकर्ता को फिर से साइन इन करने के लिए कहा जा सकता है. उदाहरण के लिए, आईपी अलग-अलग भौगोलिक क्षेत्रों के आईपी.

  1. सेशन के दावों का इस्तेमाल करके, उस आईपी पते को ट्रैक करना जिससे उपयोगकर्ता साइन इन करता है:

    Node.js के लिए

    exports.beforeSignIn = functions.auth.user().beforeSignIn((user, context) => {
      return {
        sessionClaims: {
          signInIpAddress: context.ipAddress,
        },
      };
    });
    
  2. जब कोई उपयोगकर्ता ऐसे संसाधनों को ऐक्सेस करने की कोशिश करता है जिनके लिए Firebase से पुष्टि करने की सुविधा की ज़रूरत होती है, तो अनुरोध में मौजूद आईपी पते की तुलना, साइन इन करने के लिए इस्तेमाल किए गए आईपी पते से करें:

    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!' })
          });
        }
      });
    });
    

उपयोगकर्ता की फ़ोटो की स्क्रीनिंग की जा रही है

नीचे दिए गए उदाहरण में, उपयोगकर्ताओं की प्रोफ़ाइल फ़ोटो को सैनिटाइज़ करने का तरीका बताया गया है:

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,
          };
        }
      });
});

इमेज की पहचान करने और उन्हें सैनिटाइज़ करने के तरीके के बारे में ज़्यादा जानने के लिए, Cloud Vision दस्तावेज़ देखें.

किसी उपयोगकर्ता के आइडेंटिटी प्रोवाइडर OAuth क्रेडेंशियल को ऐक्सेस करना

नीचे दिए गए उदाहरण में, Google से साइन इन करने वाले उपयोगकर्ता के लिए रीफ़्रेश टोकन पाने और Google Calendar API को कॉल करने के लिए उसका इस्तेमाल करने का तरीका बताया गया है. रीफ़्रेश टोकन को ऑफ़लाइन ऐक्सेस के लिए सेव किया जाता है.

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();
          });
      });
    })
  }
});

उपयोगकर्ता कार्रवाई के लिए, reCAPTCHA Enterprise के नतीजे को बदलें

यहां दिए गए उदाहरण में, काम करने वाले यूज़र फ़्लो के लिए, reCAPTCHA Enterprise के नतीजे को बदलने का तरीका बताया गया है.

reCAPTCHA Enterprise को Firebase से पुष्टि करने की सुविधा के साथ इंटिग्रेट करने के बारे में ज़्यादा जानने के लिए, reCAPTCHA Enterprise चालू करें लेख पढ़ें.

ब्लॉक करने वाले फ़ंक्शन का इस्तेमाल, कस्टम फ़ैक्टर के आधार पर फ़्लो को अनुमति देने या ब्लॉक करने के लिए किया जा सकता है. इससे reCAPTCHA Enterprise से मिलने वाले नतीजे बदल जाते हैं.

Node.js के लिए

 const {
   auth,
 } = require("firebase-functions/v1");

exports.checkrecaptchaV1 = auth.user().beforeSignIn((userRecord, context) => {
 // Allow users with a specific email domain to sign in regardless of their recaptcha score.
 if (userRecord.email && userRecord.email.indexOf('@acme.com') === -1) {
   return {
     recaptchaActionOverride: 'ALLOW',
   };
 }

 // Allow users to sign in with recaptcha score greater than 0.5
 if (context.additionalUserInfo.recaptchaScore > 0.5) {
   return {
     recaptchaActionOverride: 'ALLOW',
   };
 }

 // Block all others.
 return {
   recaptchaActionOverride: 'BLOCK',
 };
});