The latest configuration tutorial has been synchronized to the Cloudreve official documentation
If you need a more concise version, please refer directly to the official documentation
The official documentation was also written by me
Problem Analysis#
First, configure according to the Cloudreve official documentation, and you will likely find that after configuration, uploading still reports an error (obviously, if it didn't report an error, I wouldn't be writing this article)
Open F12 to check the request; there is a cross-origin error in the console.
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.
Then check the response headers.
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
It is obvious that the cross-origin header is missing.
Here we will compare with the response headers from 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
Notice what is missing; the key points are:
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: ETag
The first one is for cross-origin, and the second one is needed for resumable uploads.
Solution#
First, configure the CORS rules in the Backblaze backend.
Then you will find that it doesn't help much, as the Backblaze backend page is extremely simple, and you cannot directly modify the response headers in the web backend (this is for the request headers when reading files; you cannot modify the upload headers).
So we need to modify it in the B2 CLI.
First, go to Application Keys to create a new login key (either the Master Application Key or Application Key should work; if using Application Key, set the permissions yourself).
Then download B2 CLI.
If you are a Linux user, you can run the following command to download B2 CLI
# Download the latest binary
wget https://github.com/Backblaze/B2_Command_Line_Tool/releases/latest/download/b2-linux
# Grant executable permissions
chmod +x ./b2-linux
Execute b2 account authorize
to log in, and fill in keyID
and applicationKey
as prompted.
When you see output similar to the following, it means you have logged in successfully.
$ ./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"
}
First, execute b2 bucket get <bucketName>
to list the bucket details.
{
"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
}
Note here corsRules
, you can see that the allowedOperations
only includes s3_head
and s3_get
methods (if you haven't configured cross-origin on the web side, you obviously won't see these two).
To operate files normally in Cloudreve, we also need to add s3_put
, s3_post
, and s3_delete
methods.
Additionally, to allow B2 to return ETag
for normal chunk uploads in the S3 compatible API, we need to modify the corsRules
by adding ETag
to exposeHeaders
and content-type
to allowedHeaders
.
After modification, it should look like this:
"corsRules": [
{
"allowedHeaders": [
"authorization",
"range",
"content-type"
],
"allowedOperations": [
"s3_head",
"s3_get",
"s3_put",
"s3_post",
"s3_delete"
],
"allowedOrigins": [
"*"
],
"corsRuleName": "s3DownloadFromAnyOriginWithUpload",
"exposeHeaders": ["ETag"],
"maxAgeSeconds": 3600
}
]
Since uploading files through Cloudreve only requires the S3 compatible API, I directly removed the B2 parts.
If you want better security, you can replace the asterisk in allowedOrigins
with your Cloudreve domain name.
After modifying, use the command b2 bucket update <bucketName> --cors-rules 'configuration json'
to update the configuration.
After updating, it will output the complete configuration again; check if it is correct.
$ ./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
}
At this point, there should be no issues.
Try uploading the file again, and the problem is resolved.
This article was synchronized and updated to xLog by Mix Space
The original link is https://blog.baka.plus/posts/tech/Add-Backblaze-B2-support-to-Cloudreve