我正在了解Web应用中的Firebase身份验证和存储。我的想法要求用户通过Firebase登录,然后上传图片。
我可以看到这可以通过Firebase身份验证和存储实现。但是,我想限制他们可以上传的文件数和文件大小。
是否可以在Firebase控制台(或其他位置)内控制上传?在查看了JavaScript示例之后,我看到了如何将文件放入,我可以想象编写代码来查询Firebase以获取用户的上传计数,然后限制客户端,但当然,这是一种完全不安全的方法。
如果我将此作为单页应用程序托管在GitHub页面上,我想知道是否可以在不涉及服务器的情况下设置这些限制。或者,我是否需要通过服务器代理我的上传内容,以确保我从不允许用户上传超过我打算使用的内容?
答案 0 :(得分:4)
您可以通过Firebase Storage's security rules限制用户上传的内容。
例如,这(来自链接的文档)是一种限制上传文件大小的方法:
service firebase.storage {
match /b/<your-firebase-storage-bucket>/o {
match /images/{imageId} {
// Only allow uploads of any image file that's less than 5MB
allow write: if request.resource.size < 5 * 1024 * 1024
&& request.resource.contentType.matches('image/.*');
}
}
}
但是这些规则目前无法限制用户可以上传的文件数量。
我想到的一种方法是使用固定文件名。例如,如果将允许的文件名限制为1..5,则用户只能存储五个文件:
match /public/{userId}/{imageId} {
allow write: if imageId.matches("[1-5]\.txt");
}
答案 1 :(得分:1)
如果您需要每用户存储验证,解决方案有点棘手,但可以完成。
Ps。:您需要使用云功能生成Firebase令牌,但服务器不会在中间进行上传...
https://medium.com/@felipepastoree/per-user-storage-limit-validation-with-firebase-19ab3341492d
答案 2 :(得分:0)
一种解决方案可能是使用Admin SDK来根据每天保存上载次数的Firestore文档更改存储规则。
假设您有一个userUploads/uid
字段为uploadedFiles: 0
和lastUploadedOn
的firestore集合/文档。
现在,一旦用户将文件上传到Firebase Storage(假设在限制范围内且没有错误),您就可以触发Cloud Function,该功能将读取userUploads/uid
文档并检查lastUploadedOn
字段是否为早期版本date(日期),而不是当前上传文件的日期,如果是,则将uploadedFiles
设置为1,并将lastUploadedOn
更改为上载日期时间。否则,增加uploadedFiles
的计数并将lastUpdateOn
更改为当前日期时间。一旦uploadedFiles
的值变为10(您的限制),您就可以使用Admin SDK更改存储规则。请参见示例here。然后,在userUploads/uid
文档中将计数更改为0。
但是,有一些警告。规则的更改可能需要一些时间,并且该规则应该没有合法的异步工作正在处理中。来自Admin SDK:
Firebase安全规则需要数分钟才能完全部署。使用Admin SDK部署规则时,请确保避免竞争条件,在这种情况下,您的应用立即依赖尚未完成部署的规则
我自己还没有尝试过,但是看起来可以用。再三考虑,改变规则以允许写入可能会很复杂。如果用户在第二天(规则更改后)上载,则上载错误处理程序可以触发另一个云功能以检查是否为合法请求,将规则更改回正常状态,并在一段时间后再次尝试上载,但是它将是非常糟糕的用户体验。另一方面,如果您使用计划程序云功能每天检查userUploads/uid
文档并重置值,则可能会很昂贵(每月每百万名用户18美元,读取$ 0.06 / 100K),并且如果用户处于不同的时区,对于大多数用户而言,可能无关紧要,这取决于他们是否经常上传。此外,规则有局限性
因此,针对大型用户群的每个用户规则都可以轻松达到此限制(除其他规则外)。
也许最佳解决方案可能是使用Auth Claims
。如果用户具有特定的auth声明令牌(例如canUpload: false
),则最初具有拒绝写入规则。然后在上传时触发的云功能中,当用户达到限制时附加此声明。这将是实时的,因为它会立即阻止用户,这与Admin SDK规则部署延迟相反。
要删除身份验证声明:
lastUploadedOn
是否已更改,从而删除了声明lastUploadedOn
是较早的日期,然后删除声明lastUploadedOn
早于今天,则可以对其进行检查和删除,但是它的效率低于2,因为在用户甚至不上传任何内容的情况下,它都构成了在Firestore上不必要的读取操作< / li>
在2中,如果客户端尝试跳过呼叫并具有auth声明,则他/她将无法按照安全规则阻止的方式进行上传。否则,如果没有auth声明,则他/他将通过正常过程。
注意:需要将更改身份验证声明推送到客户端。请参见此doc。