如何基于字符串创建Firestore安全文档ID [英] How to create a Firestore safe Document ID based on a string
问题描述
在我关于base64对于Firestore ID而言不安全的问题上进行了一些讨论之后
After some discussion on my question about base64 not being safe for Firestore IDs here I would like to know how one can encode a string to a Firestore "safe" Document ID.
这是问题所在:
- 我正在通过自定义身份验证服务登录用户.
- 该服务提供的用户名可能包含
/
,对于我在另一个问题中询问了base64,这并不安全,因为它包含/
I asked about the base64 in another question and that is not safe as it contains
/
因此,在不丢失外部服务提供的用户名的熵的情况下,对字符串进行编码的一种安全方法可能是安全的.这意味着可能会有一个用户名,例如
dimi/test1
和另一个dimitest1
,因此不能删除字符.So what could be a safe way to encode that string without loosing the entropy of the username that the external service provides. That means that there could be a username such as
dimi/test1
and another asdimitest1
so just stripping out characters is not an option.此外,由于该服务提供了开放的API,并且我的服务通过URL公开了文档ID,因此我不希望通过我的应用URL公开其他服务的用户名.
Also since that service has available an open API and my service exposes the document ID's via URLs I would like not to expose the other service usernames via my apps URLS.
有什么建议吗?
推荐答案
编辑
要非常快速地将字符串转换为唯一ID,请使用
crypto.createHash()
.对于给定的字符串输入,结果将是相同的.In order to transform strings into uniqueIDs very fast use
crypto.createHash()
instead. The result will be the same for a given string input.您可以使用MD5或SHA256,因为两者花费相同的时间(平均2.2秒)来计算100万个唯一ID.
You can use MD5 or SHA256 as both takes the same time, 2.2s average to calculate 1 Million unique IDs.
这是代码:
const crypto = require('crypto'); function uniqueId(string, algorithm = 'md5') { return crypto.createHash(algorithm).update(string).digest('hex'); } console.log('started'); console.time('generateIDsMD5') for (let i = 0; i < 1000000; i++) { uniqueId('a string ' + i); } console.timeEnd('generateIDsMD5'); console.time('generateIDsSHA256') for (let i = 0; i < 1000000; i++) { uniqueId('a string ' + i, 'sha256'); } console.timeEnd('generateIDsSHA256'); // For instance, It will take around 2.2s average // to generate 1Million Unique IDs with MD5 or SHA256 encryption console.log('MD5 string ', uniqueId('a string ' + 1)); console.log('MD5 sameString ', uniqueId('a string ' + 2)); console.log('MD5 sameString ', uniqueId('a string ' + 2)); console.log('SHA256 string ', uniqueId('a string ' + 1, 'sha256')); console.log('SHA256 sameString ', uniqueId('a string ' + 2, 'sha256')); console.log('SHA256 sameString ', uniqueId('a string ' + 2, 'sha256')); console.log('finished');
上级答案
我改编了Firebase的代码,并通过一些自定义测试将其直接在您的node.js上可用.100万个ID最多需要3s,100.000个ID最多需要300ms,这是您考虑的日常使用方法.
I adapted the code from Firebase and made it available directly on your node.js with some custom test for you. It takes up to 3s for 1 Million IDs, and only 300ms for 100.000 IDs which is your considered daily usage approach.
如果在node.js环境中运行,它使用
crypto
被认为非常安全.This uses
crypto
considered very safe if run in node.js environment.以下是使用示例包装的函数:
here is the function wrapped with usage example:
const crypto = require('crypto'); function autoId(bytesLength) { const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; let autoId = ''; while (autoId.length < bytesLength) { const bytes = crypto.randomBytes(40); bytes.forEach(b => { // Length of `chars` is 62. We only take bytes between 0 and 62*4-1 // (both inclusive). The value is then evenly mapped to indices of `char` // via a modulo operation. const maxValue = 62 * 4 - 1; if (autoId.length < bytesLength && b <= maxValue) { autoId += chars.charAt(b % 62); } }); } return autoId; } console.log('started'); console.time('generateIDs') for (let i = 0; i < 1000000; i++) { autoId(20); } console.timeEnd('generateIDs'); // For instance, It will take around 3s average // to generate 1 Million Unique IDs with 20 bytes length console.log('example 20bytes ', autoId(20)); console.log('example 40bytes ', autoId(40)); console.log('example 60bytes ', autoId(60)); console.log('finished');
只需使用
node thisfile.js
,您将看到结果.Simply use
node thisfile.js
and you will see your result.由于firebase主要是开源的,因此我们可以在
node.js
中找到用于在其中生成ID的官方uniqueId生成器:Since firebase is mainly open source we can find the official uniqueId generator used in
node.js
to generate the IDs here: https://github.com/googleapis/nodejs-firestore/blob/4f4574afaa8cf817d06b5965492791c2eff01ed5/dev/src/util.ts#L52重要
如果您要加入2个ID,请不要使用任何斜杠
/
,因为您知道这是不允许的,而应使用下划线_
或自此以来不使用任何斜杠您可以控制ID的长度,因此您应该知道如何相应地拆分ID(40字节包含2个ID,例如20字节).If you are going to join 2 IDs, do not use any slash
/
, as you know it is not allowed, instead use underscore_
or nothing at all since you have control of the length of an ID, therefore you should know how to split the ID accordingly (40 bytes contain 2 IDs of 20 bytes for instance).Document Ids中的firestore限制为1500个字节,因此您可以玩很多.
The limitation of firestore in Document Ids is 1500 bytes so you have plenty to play with.
更多信息: https://firebase.google.com/docs/firestore/quotas#limits
这篇关于如何基于字符串创建Firestore安全文档ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!