Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django csrf for api that works with ios apps

I am building an ios app that communicates with the server for getting the data.

If its just a normal app, I can send csrf token via forms (since all from same domain). But, for ios apps, I dont think I can set csrf token .

So, when making requests from ios apps, to the server, I am getting error regarding csrf. So, whats the solution for this? Disabling this csrf feature or some other better way ? This is my first ios app, so please tell me a better way so i will follow that.

like image 526
user2349115 Avatar asked May 04 '13 06:05

user2349115


1 Answers

For those URLs ("API end points") that your iOS app is accessing, you will need to specify @csrf_exempt on the corresponding view functions to disable csrf protection.

More details here - https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#django.views.decorators.csrf.csrf_exempt

And protect those urls via other authentication methods, such as session authentication.

For your authentication purposes, you can easily take reference to what django rest framework and django tastypie has done. Both use SessionAuthentication classes to handle authentication and protect the exposed urls (API endpoints) that your iOS app can connect to.

References:-

  • http://django-rest-framework.org/api-guide/authentication.html
  • https://django-tastypie.readthedocs.org/en/latest/authentication_authorization.html

Django tastypie also has an authorization class, which is not to be confused with authentication. It also has an APIKey authorization class which becomes useful when you do want to expose your django URLs to other 3rd party developers who may want to build an app of their own to talk to your django URLs to access data (think "facebook APIs"). Each 3rd party developer can in essence be provided a unique API and because you have the APIKeyAuthorization class and a unique API Key provided to each 3rd party app, you can be sure that only "authorized" apps can consume your django URLs. This is the essence of how various big platforms like "Google+" or "Facebook" etc work.

Details of how django's csrf works

https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#how-it-works

The CSRF protection is based on the following things:

A CSRF cookie that is set to a random value (a session independent nonce, as it is called), which other sites will not have access to.

This cookie is set by CsrfViewMiddleware. It is meant to be permanent, but since there is no way to set a cookie that never expires, it is sent with every response that has called django.middleware.csrf.get_token() (the function used internally to retrieve the CSRF token).

A hidden form field with the name ‘csrfmiddlewaretoken’ present in all outgoing POST forms. The value of this field is the value of the CSRF cookie.

This part is done by the template tag.

For all incoming requests that are not using HTTP GET, HEAD, OPTIONS or TRACE, a CSRF cookie must be present, and the ‘csrfmiddlewaretoken’ field must be present and correct. If it isn’t, the user will get a 403 error.

This check is done by CsrfViewMiddleware.

In addition, for HTTPS requests, strict referer checking is done by CsrfViewMiddleware. This is necessary to address a Man-In-The-Middle attack that is possible under HTTPS when using a session independent nonce, due to the fact that HTTP ‘Set-Cookie’ headers are (unfortunately) accepted by clients that are talking to a site under HTTPS. (Referer checking is not done for HTTP requests because the presence of the Referer header is not reliable enough under HTTP.)

This ensures that only forms that have originated from your Web site can be used to POST data back.

like image 151
Calvin Cheng Avatar answered Oct 27 '22 23:10

Calvin Cheng