Search code examples
djangocorsdjango-admindigital-ocean-spacescross-origin-resource-policy

Django admin Resource Policy COEP ERR_BLOCKED_BY_RESPONSE


The static files of my Django admin site are on a S3 bucket (DigitalOcean Spaces actually) and in the Console I get a ERR_BLOCKED_BY_RESPONSE.NotSameOriginAfterDefaultedToSameOriginByCoep 200

In the network panel all the static files are considered 3rd party and blocked for this reason (not same origin)

The response to any one of these files contains a not set cross-origin-resource-policy error which says:

To use this resource from a different origin, the server needs to specify a cross-origin resource policy in the response headers.

What I tried :

  • Following the error message, I tried to set a response header on the ressources, something like Cross-Origin-Resource-Policy: cross-origin. But in a DigitalOcean Spaces I cannot set headers other than Content-Type, Cache-Control, Content-Encoding, Content-Disposition and custom x-amz-meta- headers.
  • I tried to extend the Django admin/base.html template, duplicate a few link tags and manually set a crossorigin attribute to them. This way the resources are queried twice, one query is blocked as before and the other one is working. The only difference in the headers is that the Origin is set. Is there a way to tell Django to add a crossorigin attribute to all link and script and img tags of the Django admin templates ?
  • I tried to remove the Cross-Origin-Opener-Policy and Cross-Origin-Embeder-Policy headers on the ingress loadbalancer, which I guess cause the blocking, by setting them to unsafe-none. Even though I think it should work with the policy, the change had no effect on the problem which I don't understand.

What I didn't try:

  • I found this tutorial explaining how to set custom headers on S3 Responses. The idea is to have a Lambda function in front modifying a x-amz- header to a standard header. Not sure I can easily replicate this with DigitalOcean Functions.

My workaround:

  • The ugly hack is to duplicate all Django admin templates and manually add a crossorigin attribute where needed.

I don't know where this comes from, a few weeks ago it was all good. Any help appreciated.


Solution

  • With HTTP 2+ it's more efficient to serve assets from the same domain, as they can be served on a single connection.

    Whitenoise is a popular solution for doing so with minimal configuration: ​https://whitenoise.evans.io/en/stable/

    This solved the problem for me.

    Thanks to Adam Johnson from djangoproject.