Authenticating using a username & password in a Django Rest Framework API is very straight forward in the browser, you type in the login URL, enter your username and password and login. The process is different when using an HTTP client like Postman because there are some headers you need to manually set first. I’ll show you how.
Cross Site Request Forgery(CSRF) protection
Django provides easy to use protection against Cross SIte Request Forgery. The Django docs describe CSRF attacks as a type of attack that “occurs when a malicious website contains a link, a form button or some JavaScript that is intended to perform some action on your website, using the credentials of a logged-in user who visits the malicious site in their browser.”. To protect you from this type of attack, Django requires that every form submission or HTTP POST request include a CSRF token.
CSRF tokens are random, unique, secret and unpredictable values that are generated by Django and transmitted to the client application in such a way that it is included in subsequent HTTP requests made by the client. When the client makes requests to the Django server, Django will check to see if the client’s request contains this token. If the request does not contain the CSRF token, it is rejected.
To put it simply, Django knows that there are malicious users who could attempt to impersonate legitimate users. So it adds a layer of security by requiring each client that connects with it to provide a token or secret key that only Django and that particular client know about. Since attackers cannot predict the CSRF token that will be issued to a user, it makes it impossible to construct a request that Django will honour without all the parameters.
This is what makes logging in or authenticating with a Django API challenging in clients such as Postman. Having this knowledge of how authentication works helps to make the process simple.
Authenticating
Authenticating with Django is a three step process:
- Get the CSRF token from the Django server
- Construct the HTTP POST request and include the
X-CSRF
header - Submit form data
Getting the CSRF token
The first step is to get issued a CSRF token. To do this, visit the authentication URL. In most Django Rest Framework applications, this is /auth/login . This page has this familiar login form when viewed from a browser:
When you land on this page, Django issues your client application a csrf token behind the scenes and says something like “hey, you’re new here, here’s a secret token that’s unique to you. Use it every time you want to talk to me so I know its you okay?”. Next, you fill out your credentials and hit the log in button. Your browser sends your credentials in the HTTP POST request it makes and adds a special CSRF header with the csrf token it got from Django when it first landed on this page.
Django will see this and allow the login.
To authenticate in Postman, the same general steps apply. You first have to make a HTTP GET request without any parameters or authorisation to this endpoint in order to get the CSRF token.
After sending the HTTP GET request you will get a csrftoken
cookie as shown above. This is something you’ll want to pass as a request header in your next HTTP POST request. Lets setup the HTTP POST request.
In the Body tab, enter your credentials under the form-data section. Next, add the csrf header:
The name of the header is X-CSRFToken
. Set it to the value from the csrftoken
cookie you got in the previous step. Once you have done this, you’re ready to authenticate. Hit the “Send” button and Django should now allow you to authenticate with no trouble.