TLDR::这是关于从task.snapshot.ref.getDownloadURL()
及其各自的downloadToken
返回的URL的问题。它询问token
的主要角色和功能是什么,以及是否需要由安全规则公开使用的文件。
我刚刚完成了有关将文件上传和下载到Firebase Storage的教程指南,该指南位于 https://firebase.google.com/docs/storage/web/upload-files 和 Youtube tutorial from the Firebase official channel)上。
我正在其中一个Firebase Web应用程序(React + Firebase)中为博客部分构建内容管理系统。
我有一个组件,管理员可以选择一个图像并将其上传到Firebase存储桶,以显示在特定博客文章中。特定blogPost
的所有图像都应位于特定blog-post-slug
的文件夹中。
示例:
//bucket/some-blog-post-slug/image1.jpg
当管理员在<input type='file'/>
上选择新文件时运行的代码:
function onFileSelect(e) {
const file = e.target.files[0];
const storageRef = firebase.storage().ref('some-slug/' + file.name);
const task = storageRef.put(file);
task.on('state_changed',
function progress(snapshot) {
setPercent((snapshot.bytesTransferred / snapshot.totalBytes) * 100);
},
function error(err) {
console.log(err);
},
function complete() {
console.log('Upload complete!');
task.snapshot.ref.getDownloadURL().then(function(downloadURL) {
console.log('File available at', downloadURL);
props.changeImageSrc(downloadURL);
});
}
);
}
上面的代码返回downloadURL
,该文件将保存到blogPost
文档内的Firestore中。
downloadURL
具有以下格式:
https://firebasestorage.googleapis.com/v0/b/MYFIREBASEAPP.appspot.com/o/some-slug%2FILE_NAME.jpg?alt=media&token=TOKEN_VALUE
您会看到它带有“基本URL”: https://firebasestorage.googleapis.com/v0/b/MYFIREBASEAPP.appspot.com/o/some-slug%2FILE_NAME.jpg
basicURL 后面附加了以下GET参数:
alt=media
和token=TOKEN_VALUE
我不知道会得到令牌,所以我现在正在测试其行为以了解更多信息。
允许读取具有存储行为:
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write;
}}}
{
"name": "some-slug/FILE_NAME.jpg",
"bucket": "MYBUCKET",
"generation": "GENERATION_NUMBER",
"metageneration": "1",
"contentType": "image/jpeg",
"timeCreated": "2019-06-05T13:53:57.070Z",
"updated": "2019-06-05T13:53:57.070Z",
"storageClass": "STANDARD",
"size": "815155",
"md5Hash": "Mj4aCPs21NUNxXpKg1bHirFIO0A==",
"contentEncoding": "identity",
"contentDisposition": "inline; filename*=utf-8''FILE_NAME.jpg",
"crc32c": "zhkQMQ==",
"etag": "CKu4a1+u2+0ucI412CEAE=",
"downloadTokens": "TOKEN_VALUE"
}
显示图像。
当我访问basicURL时?alt = media&token = TOKEN_VALUE
限制存储的行为:
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}}}
{
"error": {
"code": 403,
"message": "Permission denied. Could not perform this operation"
}
}
{
"error": {
"code": 403,
"message": "Permission denied. Could not perform this operation"
}
}
结论和问题
在我看来,安全规则allow read: if request.auth != null;
应该已经阻止了对未授权用户的任何读取,但是使用TOKEN
参数,即使没有auth
对象的请求也可以访问该文件(注意:运行上述测试时,我尚未登录。)
我知道问一个以上的问题不是最佳实践,但在这种情况下,我认为有必要:
问题1:
此令牌的主要作用是什么?为什么它取代了auth
规则?
问题2:
我希望这些图像可以公开获得,因为博客部分适用于所有用户。我应将哪个URL保存到Firestore?
选项1:允许所有人阅读,只需保存basicURL。
选项2:限制读取并保存basicURL +令牌。
问题3:
要显示<image src="imgSrc">
标签中的图像,我是否需要alt=media
参数?还是以FILE_NAME结尾的basicURL足够好吗?
编辑:问题3答案:刚刚对其进行了测试,发现alt=media
GET参数对于在<img>
标签内显示图像是必需的。
注意::如果您上传相同的文件并替换旧文件,则每次都会得到一个不同的token
,而旧的token
则无效。>
答案 0 :(得分:0)
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write;
}
}
}
这是Firebase存储的安全权限。所有类型的数据(图像,视频等)
答案 1 :(得分:0)
不幸的是,https://firebase.google.com/docs/storage/web/create-reference中描述的方法没有向请求和存储规则添加授权数据,例如
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
返回permission denied
,
使用AngularFireStorage模块可以解决此问题。
import { AngularFireStorage } from '@angular/fire/storage';
constructor(
private storage: AngularFireStorage
) {
}
getFileUrl(path: string): Observable<string> {
const storageRef = this.storage.ref(path);
return from(storageRef.getDownloadURL());
}