doccors
doccors
This upload provider will make it possible to use Cloudflare R2 via Cloudflare CDN
public access endpoint.
npm version
strapi-provider-cloudflare-r2
Installation
# using yarn
yarn add strapi-provider-cloudflare-r2
# using npm
npm install strapi-provider-cloudflare-r2 --save
# using pnpm
pnpm add strapi-provider-cloudflare-r2
Configuration
See the documentation about using a provider for information on installing and
using a provider. To understand how environment variables are used in Strapi,
please refer to the documentation about environment variables.
Provider Configuration
// ...
upload: {
config: {
provider: "strapi-provider-cloudflare-r2",
providerOptions: {
accessKeyId: env("CF_ACCESS_KEY_ID"),
secretAccessKey: env("CF_ACCESS_SECRET"),
/**
* `https://<ACCOUNT_ID>.r2.cloudflarestorage.com`
*/
endpoint: env("CF_ENDPOINT"),
params: {
Bucket: env("CF_BUCKET"),
},
/**
* Set this Option to store the CDN URL of your files and not the R2
endpoint URL in your DB.
* This option is required to upload files larger than 5MB, and is highly
recommended to be set.
*/
cloudflarePublicAccessUrl: env("CF_PUBLIC_ACCESS_URL"),
/**
* Sets if all assets should be uploaded in the root dir regardless the
strapi folder.
* By default it is false
*/
pool: false,
},
actionOptions: {
upload: {},
uploadStream: {},
delete: {},
},
},
},
// ...
});
endpoint: https://<ACCOUNT_ID>.r2.cloudflarestorage.com
accessKeyId: You need to click on Manage R2 API Tokens to create a new token.
secretAccessKey: You need to click on Manage R2 API Tokens to create a new
token.
Due to the default settings in the Strapi Security Middleware you will need to
modify the contentSecurityPolicy settings to properly display thumbnail previews in
the Media Library. You should replace the strapi::security string with the object
below instead as explained in the middleware configuration documentation.
./config/middlewares.js
// ...
name: "strapi::security",
config: {
contentSecurityPolicy: {
useDefaults: true,
directives: {
"img-src": [
"'self'",
"data:",
"blob:",
"market-assets.strapi.io",
env("CF_PUBLIC_ACCESS_URL") ?
env("CF_PUBLIC_ACCESS_URL").replace(/^https?:\/\//, "") : "",
],
"media-src": [
"'self'",
"data:",
"blob:",
"market-assets.strapi.io",
env("CF_PUBLIC_ACCESS_URL") ?
env("CF_PUBLIC_ACCESS_URL").replace(/^https?:\/\//, "") : "",
],
upgradeInsecureRequests: null,
},
},
},
},
// ...
];
As the Clouflare R2 spec follows the AWS S3 spec we make use of aws-sdk package to
communicate with Cloudflare R2. Because of this dependency all AWS_... env
variables used to configure the aws-sdk are still beeing pulled in by this
dependency. If you do not want to configure any special functionality of the aws-
sdk then make sure to remove all AWS_... env variables in you deployment.
Bucket CORS Configuration
"AllowedOrigins": ["*"],
"AllowedMethods": ["GET"]
More safe would be to only allow it from your Strapi deployment Origins (better for
production):
"AllowedMethods": ["GET"]
}
]
Products
R2
Buckets
Configure CORS
Configure CORS
While CORS can help protect your data from malicious websites, CORS is also used to
interact with objects in your bucket and configure policies on your bucket.
CORS is used when you interact with a bucket from a web browser, and you have two
options:
Set a bucket to public: This option makes your bucket accessible on the Internet as
read-only, which means anyone can request and load objects from your bucket in
their browser or anywhere else. This option is ideal if your bucket contains images
used in a public blog.
Presigned URLs: Allows anyone with access to the unique URL to perform specific
actions on your bucket.
Prerequisites
An R2 bucket with at least one object. If you need to create a bucket, refer to
Create a public bucket.
A domain you can use to access the object. This can also be a localhost.
(Optional) Access keys. An access key is only required when creating a
presigned URL.
To use CORS with a public bucket, ensure your bucket is set to allow public access.
Next, add a CORS policy to your bucket to allow the file to be shared.
Use CORS with a presigned URL
Presigned URLs are an S3 concept that contain a special signature that encodes
details of an S3 action, such as GetObject or PutObject. Presigned URLs are only
used for authentication, which means they are generally safe to distribute publicly
without revealing any secrets.
Create a presigned URL
You will need a pair of S3-compatible credentials to use when you generate the
presigned URL.
The example below shows how to generate a presigned PutObject URL using the @aws-
sdk/client-s3 ↗ package for JavaScript.
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
const S3 = new S3Client({
endpoint: "https://4893d737c0b9e484dfc37ec392b5fa8a.r2.cloudflarestorage.com",
credentials: {
accessKeyId: "7dc27c125a22ad808cd01df8ec309d41",
secretAccessKey:
"1aa5c5b0c43defdb88f567487c071d17e234126133444770a706ae09336c57a4",
},
region: "auto",
});
const url = await getSignedUrl(
S3,
new PutObjectCommand({
Bucket: bucket,
Key: object,
}),
{
expiresIn: 60 * 60 * 24 * 7, // 7d
},
);
console.log(url);
Test the presigned URL by uploading an object using cURL. The example below would
upload the 123 text to R2 with a Content-Type of text/plain.
Terminal window
The following fields in an R2 CORS policy map to HTTP response headers. These
response headers are only returned when the incoming HTTP request is a valid CORS
request.
Field Name Description Example
AllowedOrigins Specifies the value for the Access-Control-Allow-Origin header R2
sets when requesting objects in a bucket from a browser. If a website at
www.test.com needs to access resources (e.g. fonts, scripts) on a custom domain of
static.example.com, you would set https://www.test.com as an AllowedOrigin.
AllowedMethods Specifies the value for the Access-Control-Allow-Methods header
R2 sets when requesting objects in a bucket from a browser.GET, POST, PUT
AllowedHeaders Specifies the value for the Access-Control-Allow-Headers header
R2 sets when requesting objects in this bucket from a browser.Cross-origin requests
that include custom headers (e.g. x-user-id) should specify these headers as
AllowedHeaders. x-requested-by, User-Agent
ExposeHeaders Specifies the headers that can be exposed back, and accessed by,
the JavaScript making the cross-origin request. If you need to access headers
beyond the safelisted response headers ↗, such as Content-Encoding or cf-cache-
status, you must specify it here. Content-Encoding, cf-cache-status, Date
MaxAgeSeconds Specifies the amount of time (in seconds) browsers are allowed to
cache CORS preflight responses. Browsers may limit this to 2 hours or less, even if
the maximum value (86400) is specified. 3600
Example
This example shows a CORS policy added for a bucket that contains the Roboto-
Light.ttf object, which is a font file.
The AllowedOrigins specify the web server being used, and localhost:3000 is the
hostname where the web server is running. The AllowedMethods specify that only GET
requests are allowed and can read objects in your bucket.
[
{
"AllowedOrigins": ["http://localhost:3000"],
"AllowedMethods": ["GET"]
}
]
In general, a good strategy for making sure you have set the correct CORS rules is
to look at the network request that is being blocked by your browser.
Make sure the rule's AllowedOrigins includes the origin where the request is
being made from. (like http://localhost:3000 or https://yourdomain.com)
Make sure the rule's AllowedMethods includes the blocked request's method.
Make sure the rule's AllowedHeaders includes the blocked request's headers.
Also note that CORS rule propagation can, in rare cases, take up to 30 seconds.
Common Issues