Cloud Firestore:强制执行唯一的用户名 [英] Cloud Firestore: Enforcing Unique User Names

查看:86
本文介绍了Cloud Firestore:强制执行唯一的用户名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题

我已经多次(在Firebase实时数据库的情况下)看到了这个问题,但是我没有看到有说服力的答案.问题陈述非常简单:

I have seen this question several times (also in the context of the Firebase Real-Time Database), but I haven't seen a convincing answer to it. The problem statement is fairly simple:

(经过身份验证的)用户如何选择尚未使用的用户名?

首先,为什么:用户身份验证后,他们将具有唯一的用户ID.但是,许多网络应用程序都允许用户选择显示名称"(用户希望在网站上显示的方式),以保护用户的个人数据(例如真实姓名).

First of all, the why: After a user authenticates, they have a unique user ID. Many web-apps, however, let the user choose a "display name" (how the user wants to appear on the website), in order to protect the users personal data (like real name).

用户集合

鉴于以下数据结构,可以为每个用户存储用户名和其他数据:

Given a data structure like the following it is possible to store a username along with other data for each user:

/users  (collection)
    /{uid}  (document)
        - name: "<the username>"
        - foo: "<other data>"

但是,没有什么可以阻止另一个用户(具有不同的{uid})在其记录中存储相同的name.据我所知,没有安全规则"可让我们检查name是否已被另一个用户使用.

However, nothing prevents another user (with a different {uid}) to store the same name in their record. As far as I know, there is no "security rule" that allows us to check if the name has already been by another user.

注意:可以进行客户端检查,但不安全,因为恶意客户端可能会忽略该检查.

Note: A client side check is possible, but unsafe as a malicious client could omit the check.

反向映射

受欢迎的解决方案正在创建具有反向映射的集合:

Popular solutions are creating a collection with a reverse mapping:

/usernames  (collection)
    /{name}  (document)
       - uid: "<the auth {uid} field>"

鉴于此反向映射,可以编写安全规则来强制用户名尚未被使用:

Given this reverse mapping, it is possible to write a security rule to enforce that a username is not already taken:

match /users/{userId} {
  allow read: if true;
  allow create, update: if
      request.auth.uid == userId &&
      request.resource.data.name is string &&
      request.resource.data.name.size() >= 3 &&
      get(/PATH/usernames/$(request.resource.data.name)).data.uid == userId;
}

并强制用户首先创建用户名文档:

and to force a user to create a usernames document first:

match /usernames/{name} {
  allow read: if true;
  allow create: if
      request.resource.data.size() == 1 &&
      request.resource.data.uid is string &&
      request.resource.data.uid == request.auth.uid;
}

我相信解决方案已经完成了一半.但是,仍然存在一些未解决的问题.

I believe the solution is half-way there. However, there are still a few unsolved issues.

其余问题/问题

此实现已经涉及很多,但它甚至无法解决想要更改用户名(需要删除记录或更新规则等)的用户的问题

This implementation is quite involved already but it doesn't even solve the problem of users that want to change their user name (requires record deletion or update rules, etc.)

另一个问题是,没有什么可以阻止用户在usernames集合中添加多个记录,从而有效地抢夺所有好的用户名以破坏系统.

Another issue is, nothing prevents a user from adding multiple records in the usernames collection, effectively snatching all good usernames to sabotage the system.

对于问题:

  • 是否有一种更简单的解决方案来强制使用唯一的用户名?
  • 如何防止垃圾邮件usernames收集?
  • 如何使用户名检查不区分大小写?
  • Is there a simpler solution to enforce unique usernames?
  • How can spamming the usernames collection be prevented?
  • How can the username checks be made case-insensitive?

我还尝试使用/usernames集合的另一个exists()规则来强制users的存在,然后提交批处理写入操作,但是,这似乎不起作用("缺少或不足权限"错误).

I tried also enforcing existence of the users, with another exists() rule for the /usernames collection and then committing a batch write operation, however, this doesn't seem to work ("Missing or insufficient permissions" error).

另一个注意事项:我已经看到了客户端检查的解决方案. 但这些都不安全.任何恶意客户端都可以修改代码,并省略检查.

Another note: I have seen solutions with client-side checks. BUT THESE ARE UNSAFE. Any malicious client can modify the code, and omit checks.

推荐答案

@asciimike是Firebase安全规则开发人员. 他说,目前尚无办法对文档的密钥实施唯一性. https://twitter.com/asciimike/status/937032291511025664

@asciimike on twitter is a firebase security rules developer. He says there is currently no way to enforce uniqueness on a key on a document. https://twitter.com/asciimike/status/937032291511025664

由于firestore基于Google Cloud datastore,因此它继承了此问题.自2008年以来,这是一个长期存在的要求. https://issuetracker.google.com/issues/35875869#c14

Since firestore is based on Google Cloud datastore it inherits this issue. It's been a long standing request since 2008. https://issuetracker.google.com/issues/35875869#c14

但是,您可以使用firebase functions和一些严格的security rules来实现自己的目标.

However, you can achieve your goal by using firebase functions and some strict security rules.

您可以在介质上查看我的整个建议解决方案. https://medium.com/@jqualls/firebase-firestore-unique-constraints -d0673b7a4952

You can view my entire proposed solution on medium. https://medium.com/@jqualls/firebase-firestore-unique-constraints-d0673b7a4952

这篇关于Cloud Firestore:强制执行唯一的用户名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆