19

After searching the internet, people normally deal with this situation---the front-end is generated by django view function which can send user the cookie of csrf token. When user has a request to server using ajax, people can rewrite the ajaxSend behavior which send the csrf to server.

However, my situation is that my front-end is totally separated from back-end, ie, my front-end is in a dedicated server running nginx, and I only have one html providing all of the different pages using hashbang. My back-end is running in different server using different domain name, and in this case, how does client obtain the csrf cookie? My back-end only provided json api return.

Thank you.

DB Tsai
  • 1,378
  • 1
  • 13
  • 23

3 Answers3

8

This post is quite old but for people who still wander here: For client-server setups, such as native desktop and mobile clients (and separate front end like the OP's case), it is best to use Django Rest Framework's Token Authentication. Link

Dhruv Batheja
  • 2,140
  • 1
  • 18
  • 16
  • 2
    I'm no security expert, but as far as I can tell, this is the only real way to prevent CSRF attacks using a completely decoupled frontend and backend. Otherwise, you'll have to expose an endpoint to generate a CSRF token from your backend, which defeats the point of even using a CSRF token. – Michael Hays Nov 26 '18 at 14:31
-1

If you look at the CRSF token source: you can see that all the csrf_middleware does it check the cookie against the post value. You just need to get the post value back to your server since the cookie should of already been set though ajax. If you look at the template tag source you can see that it is just taking the variable out of the context. Either stick it in your response by pulling it out of the context if it is available or calling the context processor directly. Now you just need to send it back as the POST variable crsf_token.

kagronick
  • 2,552
  • 1
  • 24
  • 29
-1

Lets say, frontend has the domain frontend.example.com, and backend domain backend.example.com. (If you are something like Django rest framework) If you can use there are two ways you can enable security layer i.e.,. CSRF Protection or CORS

For CORS,

pip install django-cors-headers

and then configuring this to INSTALLED_APPS, MIDDLEWARE_CLASSES and add the frontend domain to CORS_ORIGIN_WHITELIST.

CORS_ORIGIN_WHITELIST = (
    'frontend.example.com'
)

CORS will block any http request arising from any domains other than frontend.example.com


For CSRF,

CSRF_COOKIE_DOMAIN = ".mydomain.com"

and if you are using an Angular App, do like below,

$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
$httpProvider.defaults.withCredentials = true;

and then add headers while make a http request.

headers : {
    "x-csrftoken" : $cookies.csrftoken
}
SuperNova
  • 25,512
  • 7
  • 93
  • 64