我正在使用自定义令牌对firebase进行身份验证。我想只限制当前用户有权写入和删除图像,并授予每个人读取权限。
下面的代码是我与存储相关的快速代码
的一部分let filePath = REF_STORAGE.child("/"+(FIRAuth.auth()?.currentUser?.uid)!+"/profilepic.jpeg")
let metaData = FIRStorageMetadata()
metaData.contentType = "image/jpeg"
我目前的firebase存储规则如下所示
service firebase.storage {
match /b/test-123456789.appspot.com/o {
match /{uid}/{allPaths=**} {
allow read: if request.auth != null;
allow write: if request.auth.uid == uid;
}
}
}
当我尝试上传图片时,我收到以下错误
用户无权访问gs://test-123456789.appspot.com/MYAUTHUID/profilepic.jpeg。
但如果我将存储规则更改为低于存储规则,我可以上传图像,并且profilepic存储在/gs://test-123456789.appspot.com/123456789/profilepic.jpeg
下service firebase.storage {
match /b/test-123456789.appspot.com/o {
match /{allPaths=**} {
allow read: if request.auth != null;
allow write: if request.auth != null;
}
}
}
请让我知道如何解决这个问题。
答案 0 :(得分:2)
您的{uid}
是否包含任何特殊字符? (例如'+'符号)
注意:Firebase Support回复我这个问题正在调查中,我在3天前发送了一个错误报告:我发现调用{userid}不起作用我在Firebase存储规则中是否包含“+”符号。
我使用E.164格式的电话号码(例如:"+97234567899"
)。
我尝试了几次运行测试,他们清楚地表明{uid}返回的值存在问题:
request.auth != null;
- 工作 request.auth.uid != null;
- 工作 request.auth.uid == "+97234567899";
- 工作 request.auth.uid == uid;
- 无效 但是,我找到了绕过这个问题的方法。这就是我想出的:
<强>解决方案强>
resource.name.split('/')[position]
由于{uid}表示文件夹名称,因此可以通过使用resource.name
操作文件的完整路径字符串,将其拆分为('/')然后选择相关层次结构来提取其值。
例如:如果这是您的路径:/Images/Profiles/{uid}/profile.jpg
,则提取这样的uid:resource.name.split('/')[2]
在您的代码示例中,我会这样做:
service firebase.storage {
match /b/test-123456789.appspot.com/o {
match /{uid}/{allPaths=**} {
allow read: if request.auth != null;
allow write: if request.auth.uid == resource.name.split('/')[0];
}
}
}
修改(2017年7月28日)
Firebase支持已在一个月前回复了我的报告,此问题已经确定并且已经确定。现在正在照顾。
然而,与此同时,如果您希望通过电话号码进行身份验证(就像我一样) - 我们不应再使用自定义令牌,因为Firebase现在支持此类身份验证。
答案 1 :(得分:1)
对于仍然遇到此问题的任何人:将firebase安全规则更新为以下内容对我来说非常有用。
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth.uid != null;
}
}
}