I'm having an issue with Django static files. I'm using Django admin and Django Rest Framework. I'm trying to serve the static files for admin and DRF with an S3 bucket. I can successfully visit the URL of any file in the bucket and it will load in my browser, and the file is served over HTTPS.
I created a nested stack in CloudFormation for the S3 bucket:
Description: >
This template deploys S3 buckets for serving Django static files.
Parameters:
AppUrl:
Type: "String"
Description: "The URL for our app (e.g. mydomain.com)"
AllowedPattern: "[a-z0-9._-]+"
Resources:
AssetsBucket:
Type: "AWS::S3::Bucket"
Properties:
BucketName: !Sub ${AppUrl}-assets
AssetsBucketPolicy:
Type: "AWS::S3::BucketPolicy"
Properties:
Bucket: !Ref AssetsBucket
PolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: PublicReadForGetBucketObjects
Effect: "Allow"
Principal: "*"
Action: "s3:GetObject"
Resource: !Sub "${AssetsBucket.Arn}/static/*"
When my application starts, it runs collectstatic
and the static files are moved into the bucket. Here's the issue I'm having:
When I visit a DRF URL with the query parameter ?format=json
. This returns a JSON response, with no static files from the browsable API, and I don't see any errors. However, when I visit the browsable API or the admin interface, I seem to find one of three error messages. In Chrome, I'm either seeing two types of behavior. The HTTPS is stripped from the URL (crossed out in red), but the static assets load with one of these two errors showing up in the console:
Access to font at 'https://mydomain.com-assets.s3.amazonaws.com/static/admin/fonts/Roboto-Bold-webfont.woff' from origin 'https://api.mydomain.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
or
GET https://mydomain.com-assets.s3.amazonaws.com/static/rest_framework/css/bootstrap.min.css net::ERR_CERT_COMMON_NAME_INVALID
In Firefox, the static files don't load, the HTTPS is not stripped, and I see the following error in the network tab of the debug window:
An error occured: SSL_ERROR_BAD_CERT_DOMAIN
I have tried adding a CORS policy to the bucket using the following XML:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>
But this did not fix the HTTPS issue. Is there something I'm missing that will help me get rid of the crossed out HTTPS?
I am confident that the certificate is OK, and that the issue is not related to HTTP being requested over an HTTPS connection. I believe this is a CORS issue, so I'm not sure why adding the CORS bucket policy didn't fix this.
Also, I have django-cors-headers installed in my Django app with CORS_ORIGIN_ALLOW_ALL = True
.
Usually, the secure link fails with bad SSL bad cert error when the domain name does not match the one specified in the SSL certificate. Every certificate provider issues SSL for a particular domain name. And the browser verifies whether the certificate matches the browser URL.
Contact us ERR_CERT_COMMON_NAME_INVALID is a very popular SSL error during loading the website. In most cases, the issue is due to certificate misconfiguration on a server. However, it may appear due to antivirus and firewall or another third-party extensions and software.
If you use a wildcard certificate on your subdomain and encounter the NET::ERR_CERT_COMMON_NAME_INVALID error, it means that your SSL certificate doesn’t cover the subdomain you are trying to access. A Subject Alternative Names (SAN) certificate allows data encryption on multiple domains pointing to one site address.
Why “NET::ERR_CERT_COMMON_NAME_INVALID” Appears in Google Chrome. A common name mismatch error occurs when the domain the SSL certificate is installed on is not listed on the certificate (either as the common name, subject alternative name, or covered by a wildcard). It’s essentially like your site is wearing the wrong hat.
As per the S3 Bucket Naming Documentation, the issue seems to be with the dot in the bucket name.
When you use virtual hosted–style buckets with Secure Sockets Layer (SSL), the SSL wildcard certificate only matches buckets that don't contain periods. To work around this, use HTTP or write your own certificate verification logic. We recommend that you do not use periods (".") in bucket names when using virtual hosted–style buckets.
Slugify the name of the domain name in the bucket name (replace dot with hyphens) to make it work.
Link to the documentation: here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With