Search code examples
djangoherokuamazon-cloudfront

Getting 403 Forbidden error on post requests when serving django app on Amazon cloud front through heroku


I have a django app deployed in heroku, which was working previously, however after adding the Edge add-on, which serves your static files from Amazon cloudfront for caching, all of my post requests are getting 403 errors.

I do pass the csrf token correctly, as my post requests still work when not served from cloudfront, but on cloudfront I am getting the error that the CSRF Verification failedCSRF Verification failed

It also mentions that the referer header is missing, however I can see referer specified in the request headers in the network tab of the developer tools.

Any idea what I am missing here?


Solution

  • CloudFront removes the referer header before sending the request to the server. The following link specifies how each header is treated: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomOrigin.html#request-custom-headers-behavior

    Using the AWS CLI, I had to configure my CloudFront distribution to forward the request header as well as the csrftoken, since cookies aren't forwarded either. Instructions can be found here: https://devcenter.heroku.com/articles/edge#cloudfront-configuration

    The ForwardedValues section of my config looked like this:

    "ForwardedValues": {
        "QueryString": false,
        "Cookies": {
            "Forward": "whitelist",
            "WhitelistedNames": {
                "Quantity": 2,
                "Items": [
                    "_app_session",
                    "csrftoken",
                ]
            }
        },
        "Headers": {
            "Quantity": 2,
            "Items": [
                "Origin",
                "Referer"
            ]
        },
        "QueryStringCacheKeys": {
            "Quantity": 0
        }
    }
    

    I also had to update my django settings file to include

    CSRF_TRUSTED_ORIGINS = [<CLOUDFRONT_URL>]
    

    Note: Although the above instructions solved my issue in the original question, I did have to forward additional cookies such as "sessionid" and "messages" to get other features of the django app working.