如何使用允许列表保护在 Firebase 存储上上传的文件?
How to secure files upload on Firebase Storage, using an allow list?
Firebase Storage 有一个很好的示例,说明如何通过其安全规则功能保护文件上传:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /images {
// Cascade read to any image type at any path
match /{allImages=**} {
allow read;
}
// Allow write files to the path "images/*", subject to the constraints:
// 1) File is less than 5MB
// 2) Content type is an image
// 3) Uploaded content type matches existing content type
// 4) File name (stored in imageId wildcard variable) is less than 32 characters
match /{imageId} {
allow write: if request.resource.size < 5 * 1024 * 1024
&& request.resource.contentType.matches('image/.*')
&& request.resource.contentType == resource.contentType
&& imageId.size() < 32
}
}
}
}
但是如果您想要允许更多文件(不仅仅是图像?)怎么办?
request.resource.contentType.matches('image/.*')
中的 matches
方法根据 Firebase Documentation 接受正则表达式,因此您可以这样做:
request.resource.contentType.matches('image/jpeg|image/png|image/gif')
如果您认为自己会得到一长串 mime-types,您可能应该开始在 Firebase 规则中使用自定义函数。这是上面的相同示例,带有自定义函数和更多 mime-types:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /images {
// Cascade read to any image type at any path
match /{allImages=**} {
allow read;
}
// Allow write files to the path "images/*", subject to the constraints:
// 1) File is less than 5MB
// 2) Content type is an image
// 3) Uploaded content type matches existing content type
// 4) File name (stored in imageId wildcard variable) is less than 32 characters
match /{imageId} {
// True if the uploaded file is part of the allow-list
function isAllowedFile(request) {
// Mime-types list source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
let allowList = "audio/aac|application/x-abiword|application/x-freearc|image/avif|video/x-msvideo|application/vnd.amazon.ebook|application/octet-stream|image/bmp|application/x-bzip|application/x-bzip2|application/x-cdf|application/x-csh|text/css|text/csv|application/msword|application/vnd.openxmlformats-officedocument.wordprocessingml.document|application/vnd.ms-fontobject|application/epub+zip|application/gzip|image/gif|image/vnd.microsoft.icon|text/calendar|image/jpeg|application/json|application/ld+json|audio/midi|audio/x-midi|audio/mpeg|video/mp4|video/mpeg|application/vnd.apple.installer+xml|application/vnd.oasis.opendocument.presentation|application/vnd.oasis.opendocument.spreadsheet|application/vnd.oasis.opendocument.text|audio/ogg|video/ogg|application/ogg|audio/opus|font/otf|image/png|application/pdf|application/x-httpd-php|application/vnd.ms-powerpoint|application/vnd.openxmlformats-officedocument.presentationml.presentation|application/vnd.rar|application/rtf|application/x-sh|image/svg+xml|application/x-tar|image/tiff|video/mp2t|font/ttf|text/plain|application/vnd.visio|audio/wav|audio/webm|video/webm|image/webp|font/woff|font/woff2|application/vnd.ms-excel|application/vnd.openxmlformats-officedocument.spreadsheetml.sheet|application/xml|application/vnd.mozilla.xul+xml|application/zip|video/3gpp|audio/3gpp|video/3gpp2|audio/3gpp2|application/x-7z-compressed";
return request.resource.contentType.matches(allowList);
}
allow write: if request.resource.size < 5 * 1024 * 1024
&& isAllowedFile(request)
&& request.resource.contentType == resource.contentType
&& imageId.size() < 32
}
}
}
}
Firebase Storage 有一个很好的示例,说明如何通过其安全规则功能保护文件上传:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /images {
// Cascade read to any image type at any path
match /{allImages=**} {
allow read;
}
// Allow write files to the path "images/*", subject to the constraints:
// 1) File is less than 5MB
// 2) Content type is an image
// 3) Uploaded content type matches existing content type
// 4) File name (stored in imageId wildcard variable) is less than 32 characters
match /{imageId} {
allow write: if request.resource.size < 5 * 1024 * 1024
&& request.resource.contentType.matches('image/.*')
&& request.resource.contentType == resource.contentType
&& imageId.size() < 32
}
}
}
}
但是如果您想要允许更多文件(不仅仅是图像?)怎么办?
request.resource.contentType.matches('image/.*')
中的 matches
方法根据 Firebase Documentation 接受正则表达式,因此您可以这样做:
request.resource.contentType.matches('image/jpeg|image/png|image/gif')
如果您认为自己会得到一长串 mime-types,您可能应该开始在 Firebase 规则中使用自定义函数。这是上面的相同示例,带有自定义函数和更多 mime-types:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /images {
// Cascade read to any image type at any path
match /{allImages=**} {
allow read;
}
// Allow write files to the path "images/*", subject to the constraints:
// 1) File is less than 5MB
// 2) Content type is an image
// 3) Uploaded content type matches existing content type
// 4) File name (stored in imageId wildcard variable) is less than 32 characters
match /{imageId} {
// True if the uploaded file is part of the allow-list
function isAllowedFile(request) {
// Mime-types list source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
let allowList = "audio/aac|application/x-abiword|application/x-freearc|image/avif|video/x-msvideo|application/vnd.amazon.ebook|application/octet-stream|image/bmp|application/x-bzip|application/x-bzip2|application/x-cdf|application/x-csh|text/css|text/csv|application/msword|application/vnd.openxmlformats-officedocument.wordprocessingml.document|application/vnd.ms-fontobject|application/epub+zip|application/gzip|image/gif|image/vnd.microsoft.icon|text/calendar|image/jpeg|application/json|application/ld+json|audio/midi|audio/x-midi|audio/mpeg|video/mp4|video/mpeg|application/vnd.apple.installer+xml|application/vnd.oasis.opendocument.presentation|application/vnd.oasis.opendocument.spreadsheet|application/vnd.oasis.opendocument.text|audio/ogg|video/ogg|application/ogg|audio/opus|font/otf|image/png|application/pdf|application/x-httpd-php|application/vnd.ms-powerpoint|application/vnd.openxmlformats-officedocument.presentationml.presentation|application/vnd.rar|application/rtf|application/x-sh|image/svg+xml|application/x-tar|image/tiff|video/mp2t|font/ttf|text/plain|application/vnd.visio|audio/wav|audio/webm|video/webm|image/webp|font/woff|font/woff2|application/vnd.ms-excel|application/vnd.openxmlformats-officedocument.spreadsheetml.sheet|application/xml|application/vnd.mozilla.xul+xml|application/zip|video/3gpp|audio/3gpp|video/3gpp2|audio/3gpp2|application/x-7z-compressed";
return request.resource.contentType.matches(allowList);
}
allow write: if request.resource.size < 5 * 1024 * 1024
&& isAllowedFile(request)
&& request.resource.contentType == resource.contentType
&& imageId.size() < 32
}
}
}
}