如何在 Firebase 3.x 中禁用注册
Posted
技术标签:
【中文标题】如何在 Firebase 3.x 中禁用注册【英文标题】:How to disable Signup in Firebase 3.x 【发布时间】:2016-11-16 09:18:53 【问题描述】:我已经使用 firebase.auth().signInWithEmailAndPassword 创建了一些用户,现在想停止注册,但继续登录工作。我尝试了一些关于用户的规则,甚至完全停止写入 firebase。但是仍然可以注册。在控制台中禁用电子邮件/密码也会禁用登录。
"rules":
".read": true,
".write": false,
任何想法如何在 Firebase 3 中将安全规则应用于用户?
【问题讨论】:
【参考方案1】:Firebase 明确地将身份验证(登录应用)与授权(从应用访问数据库或存储资源)分开。
您不能在不为所有用户禁用登录的情况下禁用注册,这不是您想要的。
在典型情况下,开发人员将开始基于经过身份验证的用户保护数据库/文件访问。请参阅database security 和storage security 的文档中的相关部分。
如果您的用例是您只希望特定用户有权访问,您可能需要实施白名单:允许访问数据的用户列表。
您可以在安全规则中这样做:
"rules":
".read": "auth.uid == '123abc' || auth.uid == 'def456'",
".write": false,
或者(更好)通过将允许的 uid 列表放入您的数据库并从您的安全规则中引用该列表:
"allowedUids":
"123abc": true,
"def456": true
然后:
"rules":
".read": "root.child('allowedUids').child(auth.uid).exists()",
".write": false,
【讨论】:
感谢您的快速响应。它解决了我的问题。 不错的解决方法。仍然希望他们添加此功能。如果我们有 200 名测试人员并且必须像这样手动添加它们,那将是一团糟 我在我们的大多数大型演示项目中都采用这种方法,它实际上具有相当大的可扩展性。如果在数据库控制台中添加 UID 的工作量太大,请创建一个简单的 Web 管理页面来添加它们。然后当然只允许管理员(您在类似的白名单上跟踪)写入此位置。 谢谢!允许您禁用新注册似乎仍然是一个合理的功能,但是哦,好吧 一种可能更有效的方法是使用自定义声明 - 这样您将角色保留在用户中,而不是将允许的用户 ID 添加到数据库 firebase.google.com/docs/auth/admin/custom-claims【参考方案2】:好吧,这个问题已经有好几天了,但也许这对那些仍然想知道答案的人有所帮助,我们仍然不能简单地禁用新帐户创建,但我们可以使用 Firebase 功能:
这是使用云功能自动禁用新用户的解决方法。
const functions = require('firebase-functions');
const admin = require('firebase-admin');
exports.blockSignup = functions.auth.user().onCreate(event =>
return admin.auth()
.updateUser(event.uid, disabled: true)
.then(userRecord => console.log(`Auto blocked user: $userRecord.toJSON()`))
.catch(error => console.log(`Error auto blocking: $error`));
);
请记住,当您使用 Firebase 网络控制台创建用户或由第 3 方创建用户时,会触发此函数。 所以你必须创建,等待函数,然后启用用户。
【讨论】:
这对我有帮助:) 它有效。但是,它允许使用例如 google 提供程序和 signInWithPopup() 方法进行首次登录。看起来帐户禁用功能随后出现。虽然,这仍然可以克服,因为在 signInWithPopup() 调用之后,我们有一个 UserCredential 类型的承诺,它有一个额外的UserInfo.isNewUser 字段,我们可以立即注销用户。 这应该很简单。控制台上的一个简单按钮,用于启用或禁用新用户创建! 还要加const functions = require('firebase-functions');
。
如何处理这个错误:firebase_config 和 gcloud_project 环境变量丢失【参考方案3】:
如果您想在 android 应用中从 FirebaseUI
中删除注册选项,则必须添加以下提供程序:
new AuthUI.IdpConfig.EmailBuilder().setAllowNewAccounts(false).build());
函数如下所示:
private void FireBaseLoginUI()
List<AuthUI.IdpConfig> providers = Collections.singletonList(
new AuthUI.IdpConfig.EmailBuilder().setAllowNewAccounts(false).build());
startActivityForResult(
AuthUI.getInstance()
.createSignInIntentBuilder()
.setAvailableProviders(providers)
.setLogo(R.drawable.app_logo)
.setTheme(R.style.AuthUITheme)
.build(),
RC_SIGN_IN);
【讨论】:
这是正确的答案,但如果你按照描述的方式实现它,它会给你以下错误:java.lang.IllegalArgumentException:每个提供者只能设置一次。密码设置了两次所以要摆脱它,你需要使用这样的电子邮件提供商: List providers = Arrays.asList( new AuthUI.IdpConfig.EmailBuilder().setAllowNewAccounts(false).build ());【参考方案4】:如果您启用Cloud Identity API,那么您可以禁用用户的注册和删除帐户操作,并将其限制为Admin SDK。
您可以访问https://console.cloud.google.com/customer-identity/settings 禁用它们。
在现有项目上启用 API 时,您可能会收到此通知:
一旦禁用,使用 createUserWithEmailAndPassword
方法返回 400 错误:
"error":
"code": 400,
"message": "ADMIN_ONLY_OPERATION",
"errors": [
"message": "ADMIN_ONLY_OPERATION",
"domain": "global",
"reason": "invalid"
]
请注意,您仍然可以使用 Admin SDK 创建新用户。
可以找到相同的文档here
【讨论】:
我也帮忙了。 这是我发现的唯一不包括任何白名单解决方法的解决方案【参考方案5】:我用这个:
// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');
const admin = require("firebase-admin");
admin.initializeApp();
exports.blockSignup = functions.auth.user().onCreate(event =>
if (process.env['allowCreation'] === "false")
return admin.auth().deleteUser(event.uid);
else return Promise.resolve("letUserCreate");
);
创建好我想要的用户后,去https://console.cloud.google.com/functions,把环境变量改成false,重新部署,完成。
或者,您可以将用户添加到 firestore,并且仅当用户存在于 firestore 时才允许注册。像这样:
// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');
const admin = require("firebase-admin");
admin.initializeApp();
exports.blockSignup = functions.auth.user().onCreate(user =>
return new Promise((resolve, reject) =>
admin.firestore().collection('users').doc(user.email).get().then(doc =>
if (doc.exists)
resolve("letUserCreate");
else
reject(admin.auth().deleteUser(user.uid))
).catch(reason =>
console.error(reason)
reject(admin.auth().deleteUser(user.uid))
)
);
);
【讨论】:
【参考方案6】:如上所述,区分身份验证和授权很重要。因此,这也可以在 Firebase 之外稍微完成。例如,如果您正在构建一个 Web 应用程序,并且您希望允许特定用户列表访问给定页面,那么您可以在您的 Web 应用程序中处理它。
此示例用于执行 onCall firebase 函数。仅当用户 UID 为12345
时才执行
exports.ILoveConsole = functions.https.onCall((message, context) =>
//message is just a text
//context hold the user auth information
'use strict';
if (context && context.auth && context.auth.uid)
if(context.auth.uid === "12345")
console.log("I love security");
else
console.log("You are authenticated but not authorized");
else
console.log("You are neither authenticated nor authorized");
);
注意:如果你想做一个用户列表,你可以做一个 for 循环函数来检查你在浏览器中的授权用户数组或调用一个 firebase 函数。它们都应该在加载页面之前运行
【讨论】:
以上是关于如何在 Firebase 3.x 中禁用注册的主要内容,如果未能解决你的问题,请参考以下文章
如何在 iOS 上禁用 reCAPTCHA 验证以进行 Firebase 身份验证?
如何在 Flutter 中启用/禁用 Firebase Crashlytics
如何在 iOS 中禁用 Firebase/Core 调试消息
如何在调试模式下,在 react-native-firebase 中禁用 Crashlytics?