(如何)您可以将用户从 firebase 中注销吗?

(How) can you log a user out of firebase?

我们使用 Firebase 进行用户身份验证。

我可以在客户端登录用户,然后 运行 来自 python 应用的以下内容:

import firebase_admin
import firebase_admin.auth
from firebase_admin import credentials
from datetime import datetime

cred = credentials.Certificate('my_creds.json')
app = firebase_admin.initialize_app(cred)

firebase_admin.auth.revoke_refresh_tokens('some-user-id', app=app)
u = firebase_admin.auth.get_user('some-user-id')
print(datetime.fromtimestamp(u.tokens_valid_after_timestamp / 1000))

显示当前时间戳,至少据我了解managing user sessions documentation,它应该是撤销令牌。我认为应该做到这一点,这样我在客户端做的任何进一步操作都会失败。

然而,这不是真的。我可以弹出 'some-user-id' 已登录的控制台和 运行:

firebase.database().ref('some/key').once('value').then(function(snap){ console.log(snap.val()); });

过一会儿,我再观察一下some/key的值就好了。

这样不行。

当我 运行 firebase.auth().currentUser.reload() 然后 它实际上会断开我的会话,我将无法再获得该值。但是我想在服务器端做一些事情来做到这一点,这样来自客户端的每个后续请求都会因身份验证问题而失败。

这可能吗?如果是这样,我该怎么做?

revoke_refresh_token() 使 "refresh tokens" 无效。它不会使已经登录的用户会话无效。事实上,任何当前在会话中的 "ID tokens" 都可以在一个小时内保持有效(之后用户将被强制登录)。如果您想了解更多关于这两种令牌之间的区别,请查看this article

要防止使用旧的(撤销前的)ID 令牌访问数据库,您应该使用 Firebase 安全规则。您可以将 tokens_valid_after_timestamp 写入数据库:

auth.revoke_refresh_tokens(uid)
user = auth.get_user(uid)
revocation_second = user.tokens_valid_after_timestamp / 1000
# Write the revoke time to database as part of the
# server-side revoke operaition
metadata_ref = firebase_admin.db.reference("metadata/" + uid)
metadata_ref.set({'revokeTime': revocation_second})

然后实施一个规则来检查 ID 令牌。

{
  "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)"
      }
    }
  }
}

此配置阻止用户使用吊销前获得的 ID 令牌访问 users/{uid} 节点。

documentation 中概述了此解决方案。