Search code examples
phpdjangowordpresscurlcsrf-protection

csrf_exempt decorator not exempting


I have a wordpress site (coded with PHP) that I am using to post data to a django view. I post with this code

$ch = curl_init( $url );
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $myvars);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_REFERER, 'https://mydjangosite.com/blah/blah2/');

The function the url above goes to is using the @csrf_exempt decorator because I want to allow a cross-site post in this instance

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
@api_wrapper
def add_referral_api(request, status_slug):

However, I still receive this error in my logs

[03/Feb/2017 18:17:48] WARNING [django.request:177] Forbidden (CSRF cookie not set.): 

How can I allow such cross-site posting between trusted sites?

EDIT My Middleware Classes are as such. Note that this site uses a ssl certificate, for what it's worth, and I suspect that the extra security is causing the csrf_exemption decorator to not work as I would hope. Even still, I'd like to somehow be able to say that this one site (my WP site) is okay to receive post data from.

MIDDLEWARE_CLASSES = (
    # This middleware is for ensuring that all pages use https
    #'djangosecure.middleware.SecurityMiddleware',
    'django.middleware.gzip.GZipMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'common.middleware.XsSharing',
    'impersonate.middleware.ImpersonateMiddleware',
    'referrals.middleware.ReferralMiddleware',
)

Solution

  • After chatting with Matt, we discovered the culprit to be the @api_wrapper decorator (so, my initial intuition was right), as it was calling the @ensure_csrf_token decorator, rendering the @csrf_exempt useless. The PHP call gave a Bad Request (400), but that's out of the scope of this question.