目前最新的配置教程已同步到 Cloudreve 官方文档
如果你需要更简略的版本请直接查阅官方文档
官方文档那个也是我写的
問題分析#
首先按照 Cloudreve 官方文档 進行配置,然後你大概率會發現配置完之後上傳依然會報錯 (廢話,要是不報錯也不會寫這篇文章)
打開 F12 看一下請求,控制台這邊有一個跨域報錯
Access to XMLHttpRequest at 'https://s3.us-east-001.backblazeb2.com/xxx' from origin 'https://demo.cloudreve.org' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
然後檢查下響應標頭
Cache-Control: max-age=0, no-cache, no-store
Connection: keep-alive
Content-Length: 216
Content-Type: application/xml
Date: Wed, 19 Jun 2024 15:54:31 GMT
Server: nginx
Strict-Transport-Security: max-age=63072000
X-Amz-Id-2: aM+Y1ZDJYZBU2hn2JYjDlOMNkuWF2
X-Amz-Request-Id: 4c38if3n9n98732
很明顯,缺了跨域頭
這裡我們再拿 Cloudflare R2 的響應標頭對比下
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: ETag
Cf-Ray: 89649ob992b2d0f-LAX
Connection: keep-alive
Content-Length: 0
Date: Wed, 19 Jun 2024 15:56:54 GMT
Etag: "264f5757014d2dn3ij3ij2fc90cd7b"
Server: cloudflare
Vary: Origin, Accept-Encoding
發現缺了什麼沒有,重點在於
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: ETag
上面那個是跨域,下面那個是斷點續傳需要的
解決方案#
首先先在 Backblaze 後台配置 CORS 規則
然後你會發現並沒有什麼用,由於 Backblaze 極為 簡潔 (jian lou) 的後台頁面,你沒法直接在 Web 後台進行響應頭的修改(這裡改的是讀取文件的請求頭,上傳的沒法改)
所以我們得在 B2 CLI 進行修改
首先先去 Application Keys 新建一個登錄密鑰(這裡用 Master Application Key 或者 Application Key 應該都行,Application Key 的話自己給下權限)
然後下載 B2 CLI
如果你是 Linux 用戶,你可以運行以下的命令來下載 B2 CLI
# 下載最新二進制
wget https://github.com/Backblaze/B2_Command_Line_Tool/releases/latest/download/b2-linux
# 给予可执行权限
chmod +x ./b2-linux
執行 b2 account authorize
進行賬號登錄,根據提示填入 keyID
和 applicationKey
當你看到輸出了類似下面的一大坨東西,就說明登錄成功了
$ ./b2-linux account authorize
Backblaze application key ID: <keyID>
Backblaze application key:
{
"accountAuthToken": "<Token>",
"accountFilePath": "/home/bakaArch/.config/b2/account_info",
"accountId": "<accountID>",
"allowed": {
"bucketId": null,
"bucketName": null,
"capabilities": [
"bypassGovernance",
"deleteBuckets",
"deleteFiles",
"deleteKeys",
"listAllBucketNames",
"listBuckets",
"listFiles",
"listKeys",
"readBucketEncryption",
"readBucketNotifications",
"readBucketReplications",
"readBucketRetentions",
"readBuckets",
"readFileLegalHolds",
"readFileRetentions",
"readFiles",
"shareFiles",
"writeBucketEncryption",
"writeBucketNotifications",
"writeBucketReplications",
"writeBucketRetentions",
"writeBuckets",
"writeFileLegalHolds",
"writeFileRetentions",
"writeFiles",
"writeKeys"
],
"namePrefix": null
},
"apiUrl": "https://api001.backblazeb2.com",
"applicationKey": "<applicationKey>",
"applicationKeyId": "<applicationKeyId>",
"downloadUrl": "https://f001.backblazeb2.com",
"isMasterKey": true,
"s3endpoint": "https://s3.us-east-001.backblazeb2.com"
}
首先,執行 b2 bucket get <bucketName>
列出一下存儲桶詳情
{
"accountId": "<accountID>",
"bucketId": "<bucketID>",
"bucketInfo": {},
"bucketName": "<bucketName>",
"bucketType": "allPrivate",
"corsRules": [
{
"allowedHeaders": [
"authorization",
"range"
],
"allowedOperations": [
"b2_download_file_by_id",
"b2_download_file_by_name"
],
"allowedOrigins": [
"*"
],
"corsRuleName": "downloadFromAnyOrigin",
"exposeHeaders": null,
"maxAgeSeconds": 3600
},
{
"allowedHeaders": [
"authorization",
"range"
],
"allowedOperations": [
"s3_head",
"s3_get"
],
"allowedOrigins": [
"*"
],
"corsRuleName": "s3DownloadFromAnyOrigin",
"exposeHeaders": null,
"maxAgeSeconds": 3600
}
],
"defaultRetention": {
"mode": null
},
"defaultServerSideEncryption": {
"mode": "none"
},
"isFileLockEnabled": false,
"lifecycleRules": [],
"options": [
"s3"
],
"replication": {
"asReplicationDestination": null,
"asReplicationSource": null
},
"revision": 7
}
注意這裡 corsRules
,可以看到這裡的 allowedOperations
只有 s3_head
和 s3_get
方法(如果你沒有在 Web 端配置跨域,那這兩條顯然你也是見不到的)
而為了能夠在 Cloudreve 中正常操作文件,我們還需要為其添加 s3_put
s3_post
s3_delete
方法
同時,為了能夠在 S3 兼容 API 中正常進行分塊上傳,我們還需要允許 B2 返回 ETag
我們在前面複製的存儲桶詳情中,修改 corsRules
中的 allowedOperations
,在 exposeHeaders
中添加 ETag
,在 allowedHeaders
中添加 content-type
修改完之後應該是長這樣
"corsRules": [
{
"allowedHeaders": [
"authorization",
"range",
"content-type"
],
"allowedOperations": [
"s3_head",
"s3_get",
"s3_put",
"s3_post",
"s3_delete"
],
"allowedOrigins": [
"*"
],
"corsRuleName": "s3DownloadFromAnyOriginWithUpload",
"exposeHeaders": ["ETag"],
"maxAgeSeconds": 3600
}
]
因為通過 Cloudreve 上傳文件只需要用到 S3 兼容 API,所以我這邊直接刪去了 B2 的部分
如果你希望得到更好的安全性,可以將 allowedOrigins
中的星號換成你 Cloudreve 的域名
修改完之後,使用命令 b2 bucket update <bucketName> --cors-rules '配置json'
更新配置
更新完之後會重新輸出一遍完整配置,檢查一下是否正確
$ ./b2-linux bucket update <bucketName> --cors-rules '[
{
"allowedHeaders": [
"authorization",
"range",
"content-type"
],
"allowedOperations": [
"s3_head",
"s3_get",
"s3_put",
"s3_post",
"s3_delete"
],
"allowedOrigins": [
"*"
],
"corsRuleName": "s3DownloadFromAnyOriginWithUpload",
"exposeHeaders": ["ETag"],
"maxAgeSeconds": 3600
}
]'
{
"accountId": "<accountID>",
"bucketId": "<bucketID>",
"bucketInfo": {},
"bucketName": "<bucketName>",
"bucketType": "allPrivate",
"corsRules": [
{
"allowedHeaders": [
"authorization",
"range",
"content-type"
],
"allowedOperations": [
"s3_head",
"s3_put",
"s3_delete",
"s3_post",
"s3_get"
],
"allowedOrigins": [
"*"
],
"corsRuleName": "s3DownloadFromAnyOriginWithUpload",
"exposeHeaders": [
"etag"
],
"maxAgeSeconds": 3600
}
],
"defaultRetention": {
"mode": null
},
"defaultServerSideEncryption": {
"mode": "none"
},
"isFileLockEnabled": false,
"lifecycleRules": [],
"options": [
"s3"
],
"replication": {
"asReplicationDestination": null,
"asReplicationSource": null
},
"revision": 9
}
到這裡,應該就沒有問題了
再次嘗試上傳文件,問題解決
此文由 Mix Space 同步更新至 xLog
原始鏈接為 https://blog.baka.plus/posts/tech/Add-Backblaze-B2-support-to-Cloudreve