Google is committed to advancing racial equity for Black communities. See how.
इस पेज का अनुवाद Cloud Translation API से किया गया है.
Switch to English

उपयोगकर्ता सत्र प्रबंधित करें

फायरबेस प्रमाणीकरण सत्र लंबे समय तक रहते हैं। हर बार जब कोई उपयोगकर्ता साइन इन करता है, तो उपयोगकर्ता क्रेडेंशियल को फायरबेस प्रमाणीकरण बैकएंड पर भेजा जाता है और फायरबेस आईडी टोकन (जेडब्ल्यूटी) और रिफ्रेश टोकन के लिए एक्सचेंज किया जाता है। फायरबेस आईडी टोकन कम रहते हैं और एक घंटे तक रहते हैं; ताज़ा आईडी का उपयोग नई आईडी टोकन प्राप्त करने के लिए किया जा सकता है। ताज़ा टोकन केवल तभी समाप्त होता है जब निम्न में से कोई एक होता है:

  • उपयोगकर्ता हटा दिया गया है
  • उपयोगकर्ता अक्षम है
  • उपयोगकर्ता के लिए एक प्रमुख खाता परिवर्तन का पता लगाया जाता है। इसमें पासवर्ड या ईमेल एड्रेस अपडेट जैसी घटनाएं शामिल हैं।

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

ताज़ा ताज़ा टोकन

जब उपयोगकर्ता किसी खो जाने या चोरी होने की रिपोर्ट करता है, तो आप उपयोगकर्ता के मौजूदा ताज़ा टोकन को रद्द कर सकते हैं। इसी तरह, यदि आप एक सामान्य भेद्यता का पता listUsers या सक्रिय टोकन के व्यापक पैमाने पर रिसाव पर संदेह करते हैं, तो आप सभी उपयोगकर्ताओं को देखने और निर्दिष्ट परियोजना के लिए अपने टोकन को वापस लेने के लिए listUsers API का उपयोग कर सकते हैं।

पासवर्ड रीसेट उपयोगकर्ता के मौजूदा टोकन को भी रद्द कर देते हैं; हालाँकि, फायरबेस प्रमाणीकरण बैकएंड उस मामले में स्वतः निरसन को संभालता है। निरस्तीकरण पर, उपयोगकर्ता को साइन आउट किया जाता है और reauthenticate को संकेत दिया जाता है।

यहां एक उदाहरण कार्यान्वयन है जो किसी दिए गए उपयोगकर्ता के ताज़ा टोकन को रद्द करने के लिए व्यवस्थापक एसडीके का उपयोग करता है। व्यवस्थापक को प्रारंभ करने के लिए SDK सेटअप पृष्ठ पर दिए गए निर्देशों का पालन करें।

Node.js

// Revoke all refresh tokens for a specified user for whatever reason.
// Retrieve the timestamp of the revocation, in seconds since the epoch.
admin
  .auth()
  .revokeRefreshTokens(uid)
  .then(() => {
    return admin.auth().getUser(uid);
  })
  .then((userRecord) => {
    return new Date(userRecord.tokensValidAfterTime).getTime() / 1000;
  })
  .then((timestamp) => {
    console.log(`Tokens revoked at: ${timestamp}`);
  });

जावा

FirebaseAuth.getInstance().revokeRefreshTokens(uid);
UserRecord user = FirebaseAuth.getInstance().getUser(uid);
// Convert to seconds as the auth_time in the token claims is in seconds too.
long revocationSecond = user.getTokensValidAfterTimestamp() / 1000;
System.out.println("Tokens revoked at: " + revocationSecond);

अजगर

# Revoke tokens on the backend.
auth.revoke_refresh_tokens(uid)
user = auth.get_user(uid)
# Convert to seconds as the auth_time in the token claims is in seconds.
revocation_second = user.tokens_valid_after_timestamp / 1000
print('Tokens revoked at: {0}'.format(revocation_second))

जाओ

client, err := app.Auth(ctx)
if err != nil {
	log.Fatalf("error getting Auth client: %v\n", err)
}
if err := client.RevokeRefreshTokens(ctx, uid); err != nil {
	log.Fatalf("error revoking tokens for user: %v, %v\n", uid, err)
}
// accessing the user's TokenValidAfter
u, err := client.GetUser(ctx, uid)
if err != nil {
	log.Fatalf("error getting user %s: %v\n", uid, err)
}
timestamp := u.TokensValidAfterMillis / 1000
log.Printf("the refresh tokens were revoked at: %d (UTC seconds) ", timestamp)

सी#

await FirebaseAuth.DefaultInstance.RevokeRefreshTokensAsync(uid);
var user = await FirebaseAuth.DefaultInstance.GetUserAsync(uid);
Console.WriteLine("Tokens revoked at: " + user.TokensValidAfterTimestamp);

आईडी टोकन निरस्तीकरण का पता लगाएं

क्योंकि Firebase ID टोकन स्टेटलेस JWT हैं, आप निर्धारित कर सकते हैं कि केवल Firebase प्रमाणीकरण बैकएंड से टोकन की स्थिति का अनुरोध करके एक टोकन रद्द कर दिया गया है। इस कारण से, आपके सर्वर पर इस चेक का प्रदर्शन करना एक महंगा ऑपरेशन है, जिसमें अतिरिक्त नेटवर्क राउंड ट्रिप की आवश्यकता होती है। आप फायरबेस नियम स्थापित करके इस नेटवर्क अनुरोध को बनाने से बच सकते हैं जो चेक बनाने के लिए एडमिन एसडीके का उपयोग करने के बजाय निरसन के लिए जाँच करें।

डेटाबेस नियमों में आईडी टोकन निरस्तीकरण का पता लगाएं

डेटाबेस नियमों का उपयोग करके आईडी टोकन निरस्तीकरण का पता लगाने में सक्षम होने के लिए, हमें पहले कुछ उपयोगकर्ता-विशिष्ट मेटाडेटा संग्रहित करना होगा।

फायरबेस रियलटाइम डेटाबेस में उपयोगकर्ता-विशिष्ट मेटाडेटा अपडेट करें।

ताज़ा टोकन निरस्तीकरण टाइमस्टैम्प सहेजें। फायरबेस नियमों के माध्यम से आईडी टोकन निरस्तीकरण को ट्रैक करने की आवश्यकता है। यह डेटाबेस के भीतर कुशल जाँच के लिए अनुमति देता है। नीचे दिए गए कोड नमूनों में, पिछले अनुभाग में प्राप्त यूआईडी और निरसन समय का उपयोग करें।

Node.js

const metadataRef = admin.database().ref('metadata/' + uid);
metadataRef.set({ revokeTime: utcRevocationTimeSecs }).then(() => {
  console.log('Database updated successfully.');
});

जावा

DatabaseReference ref = FirebaseDatabase.getInstance().getReference("metadata/" + uid);
Map<String, Object> userData = new HashMap<>();
userData.put("revokeTime", revocationSecond);
ref.setValueAsync(userData);

अजगर

metadata_ref = firebase_admin.db.reference("metadata/" + uid)
metadata_ref.set({'revokeTime': revocation_second})

डेटाबेस नियम में एक चेक जोड़ें

इस चेक को लागू करने के लिए, एक नियम सेट करें, जिसमें कोई ग्राहक नहीं लिखता है, प्रति उपयोगकर्ता निरस्तीकरण समय को स्टोर करने के लिए एक्सेस लिखता है। इसे पिछले उदाहरणों में दिखाए गए अंतिम निरसन समय के यूटीसी टाइमस्टैम्प के साथ अपडेट किया जा सकता है:

{
  "rules": {
    "metadata": {
      "$user_id": {
        // this could be false as it is only accessed from backend or rules.
        ".read": "$user_id === auth.uid",
        ".write": "false",
      }
    }
  }
}

किसी भी डेटा को प्रमाणित उपयोग की आवश्यकता होती है जिसमें निम्नलिखित नियम कॉन्फ़िगर होना चाहिए। यह तर्क केवल प्रमाणित उपयोगकर्ताओं को सुरक्षित डेटा तक पहुँचने के लिए अप्रमाणित आईडी टोकन की अनुमति देता है:

{
  "rules": {
    "users": {
      "$user_id": {
        ".read": "$user_id === auth.uid && auth.token.auth_time > (root.child('metadata').child(auth.uid).child('revokeTime').val() || 0)",
        ".write": "$user_id === auth.uid && auth.token.auth_time > (root.child('metadata').child(auth.uid).child('revokeTime').val() || 0)"
      }
    }
  }
}

एसडीके में आईडी टोकन निरस्तीकरण का पता लगाएं।

अपने सर्वर में, टोकन निरस्तीकरण और आईडी टोकन सत्यापन के लिए निम्नलिखित तर्क को लागू करें:

जब उपयोगकर्ता की आईडी टोकन को सत्यापित किया जाना है, तो checkRevoked को अतिरिक्त checkRevoked बूलियन ध्वज को पारित करना verifyIdToken । यदि उपयोगकर्ता के टोकन को निरस्त कर दिया जाता है, तो उपयोगकर्ता को क्लाइंट पर साइन आउट किया जाना चाहिए या फायरबेस प्रमाणीकरण क्लाइंट एसडीके द्वारा प्रदान किए गए reauthentication एपीआई का उपयोग करके reauthenticate को कहा जाना चाहिए।

अपने प्लेटफ़ॉर्म के लिए व्यवस्थापक SDK को आरंभ करने के लिए, सेटअप पृष्ठ पर दिए गए निर्देशों का पालन करें। ID टोकन प्राप्त करने के उदाहरण verifyIdToken अनुभाग में हैं।

Node.js

// Verify the ID token while checking if the token is revoked by passing
// checkRevoked true.
let checkRevoked = true;
admin
  .auth()
  .verifyIdToken(idToken, checkRevoked)
  .then((payload) => {
    // Token is valid.
  })
  .catch((error) => {
    if (error.code == 'auth/id-token-revoked') {
      // Token has been revoked. Inform the user to reauthenticate or signOut() the user.
    } else {
      // Token is invalid.
    }
  });

जावा

try {
  // Verify the ID token while checking if the token is revoked by passing checkRevoked
  // as true.
  boolean checkRevoked = true;
  FirebaseToken decodedToken = FirebaseAuth.getInstance()
      .verifyIdToken(idToken, checkRevoked);
  // Token is valid and not revoked.
  String uid = decodedToken.getUid();
} catch (FirebaseAuthException e) {
  if (e.getAuthErrorCode() == AuthErrorCode.REVOKED_ID_TOKEN) {
    // Token has been revoked. Inform the user to re-authenticate or signOut() the user.
  } else {
    // Token is invalid.
  }
}

अजगर

try:
    # Verify the ID token while checking if the token is revoked by
    # passing check_revoked=True.
    decoded_token = auth.verify_id_token(id_token, check_revoked=True)
    # Token is valid and not revoked.
    uid = decoded_token['uid']
except auth.RevokedIdTokenError:
    # Token revoked, inform the user to reauthenticate or signOut().
    pass
except auth.InvalidIdTokenError:
    # Token is invalid
    pass

जाओ

client, err := app.Auth(ctx)
if err != nil {
	log.Fatalf("error getting Auth client: %v\n", err)
}
token, err := client.VerifyIDTokenAndCheckRevoked(ctx, idToken)
if err != nil {
	if err.Error() == "ID token has been revoked" {
		// Token is revoked. Inform the user to reauthenticate or signOut() the user.
	} else {
		// Token is invalid
	}
}
log.Printf("Verified ID token: %v\n", token)

सी#

try
{
    // Verify the ID token while checking if the token is revoked by passing checkRevoked
    // as true.
    bool checkRevoked = true;
    var decodedToken = await FirebaseAuth.DefaultInstance.VerifyIdTokenAsync(
        idToken, checkRevoked);
    // Token is valid and not revoked.
    string uid = decodedToken.Uid;
}
catch (FirebaseAuthException ex)
{
    if (ex.AuthErrorCode == AuthErrorCode.RevokedIdToken)
    {
        // Token has been revoked. Inform the user to re-authenticate or signOut() the user.
    }
    else
    {
        // Token is invalid.
    }
}

क्लाइंट पर टोकन निरस्तीकरण का जवाब दें

यदि टोकन को SDK के माध्यम से निरस्त किया जाता है, तो ग्राहक को निरसन के बारे में सूचित किया जाता है और उपयोगकर्ता से पुनर्मूल्यांकन करने या बाहर प्रवेश करने की अपेक्षा की जाती है:

function onIdTokenRevocation() {
  // For an email/password user. Prompt the user for the password again.
  let password = prompt('Please provide your password for reauthentication');
  let credential = firebase.auth.EmailAuthProvider.credential(
      firebase.auth().currentUser.email, password);
  firebase.auth().currentUser.reauthenticateWithCredential(credential)
    .then(result => {
      // User successfully reauthenticated. New ID tokens should be valid.
    })
    .catch(error => {
      // An error occurred.
    });
}

उन्नत सुरक्षा: आईपी पता प्रतिबंध लागू करें

टोकन चोरी का पता लगाने के लिए एक सामान्य सुरक्षा तंत्र अनुरोध का पता रखने के लिए है आईपी पते की उत्पत्ति। उदाहरण के लिए, यदि अनुरोध हमेशा एक ही आईपी पते (सर्वर कॉल करने वाले) से आ रहे हैं, तो एकल आईपी पते सत्र लागू किए जा सकते हैं। या, आप एक उपयोगकर्ता टोकन को रद्द कर सकते हैं यदि आप पता लगाते हैं कि उपयोगकर्ता का आईपी पता अचानक जियोलोकेशन बदल गया है या आपको एक संदिग्ध मूल से अनुरोध प्राप्त होता है।

आईपी ​​पते के आधार पर सुरक्षा जांच करने के लिए, प्रत्येक प्रमाणित अनुरोध के लिए आईडी टोकन का निरीक्षण करें और देखें कि अनुरोध का आईपी पता पिछले भरोसेमंद आईपी पते से मेल खाता है या प्रतिबंधित डेटा तक पहुंच की अनुमति देने से पहले एक विश्वसनीय सीमा के भीतर है। उदाहरण के लिए:

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 the user's previous IP addresses, previously saved.
    return getPreviousUserIpAddresses(claims.sub);
  }).then(previousIpAddresses => {
    // Get the request IP address.
    const requestIpAddress = req.connection.remoteAddress;
    // Check if the request IP address origin is suspicious relative to previous
    // 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 location change in a
    // short period of time, then it will give stronger signals of possible abuse.
    if (!isValidIpAddress(previousIpAddresses, requestIpAddress)) {
      // Invalid IP address, take action quickly and revoke all user's refresh tokens.
      revokeUserTokens(claims.uid).then(() => {
        res.status(401).send({error: 'Unauthorized access. Please login again!'});
      }, error => {
        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!' })
      });
    }
  });
});