How to use TokenAuthentication for API in django-rest-framework

Question:

I have a django project, using django-rest-framework to create api.

Want to use token base authentication system so api call for (put, post, delete) will only execute for authorized user.

I installed ‘rest_framework.authtoken’ and created token for each users.

So, now from django.contrib.auth.backends authenticate, it returns user, with auth_token as attribute. (when loged in successfully).

Now my question is how can I send the token with post request to my api and
at api side how can I verify if token is valid and belongs to the correct user?

Are there any methods in app rest_framework.authtoken to validate given user and its token?
not found this very useful!

Update (changes I made):
Added this in my settings.py:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    )
}

Also sending Token in my header but its still not working:

if new_form.is_valid:
    payload= {"createNewUser":
              { "users": request.POST["newusers"],
                "email": request.POST["newemail"]
                }
              }

    headers =  {'content-type' : 'application/json', 
                'Authorization': 'Token 6b929e47f278068fe6ac8235cda09707a3aa7ba1'}

    r = requests.post('http://localhost:8000/api/v1.0/user_list',
                      data=json.dumps(payload),
                      headers=headers, verify=False)
Asked By: Peter

||

Answers:

“how can I send the token with post request to my api”

From the docs…

For clients to authenticate, the token key should be included in the Authorization HTTP header. The key should be prefixed by the string literal “Token”, with whitespace separating the two strings. For example:

Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b

“at api side how can I verify if token is valid and belongs to the correct user?”

You don’t need to do anything, just access request.user to return the authenticated user – REST framework will deal with returning a ‘401 Unauthorized’ response to any incorrect authentication.

Answered By: Tom Christie

I finally have the django “rest-auth” package working for token authentication.
If this helps, here is the client-side jQuery code that worked for me, after you successfully log in and receive the “auth_token”:

var user_url = {API URL}/rest-auth/login
var auth_headers = {
  Authorization: 'Token ' + auth_token
}
var user_ajax_obj = {
  url : user_url,
  dataType : 'json',
  headers: auth_headers,
  success : function(data) {
    console.log('authorized user returned');
  },
  error: function(XMLHttpRequest, textStatus, errorThrown) {
    console.log('error returned from ' + user_url);
  }
};
$.ajax(
  user_ajax_obj
);
Answered By: Stefan Musarra

To answer the first half of your question:

how can I send the token with post request to my api

You can use the Python requests library. For the django-rest-framework TokenAuthentication, the token needs to be passed in the header and prefixed by the string Token (see here):

import requests
mytoken = "4652400bd6c3df8eaa360d26560ab59c81e0a164"
myurl = "http://localhost:8000/api/user_list"

# A get request (json example):
response = requests.get(myurl, headers={'Authorization': 'Token {}'.format(mytoken)})
data = response.json()

# A post request:
data = { < your post data >}
requests.post(myurl, data=data, headers={'Authorization': 'Token {}'.format(mytoken)})
Answered By: elke

If you are using coreapi. To add the Authorisation you do

import coreapi
auth = coreapi.auth.TokenAuthentication(scheme='Token', token=token_key)

Then you can do

client = coreapi.Client(auth=auth)
response = client.get(my_url)

Answered By: unlockme