35

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)
yaobin
  • 2,436
  • 5
  • 33
  • 54
Peter
  • 1,023
  • 4
  • 18
  • 23
  • Basically a duplicate: http://stackoverflow.com/questions/14838128/django-rest-framework-token-authentication – jdero Jul 09 '13 at 23:55
  • nop that post only talk about creating the tokens - I'm done with that part, and now want to know how to pass the token over http request and how to verify the given user and its token. No body talks about that part. – Peter Jul 10 '13 at 00:08
  • 1
    It is very well documented in django-rest-framework documentation.On the client side you just add header to all HTTP requests, and django-rest-framework is doing the rest on server side. If valid token was provided you will have correct user as request.user – jasisz Jul 10 '13 at 07:02
  • Do you need object level permissions (authenticated user can POST/DELETE their own instances of models) or just request level (authenticated user can perform any DELETE/POST)? – will-hart Jul 10 '13 at 11:56
  • just request level (authenticated user can perform any DELETE/POST) and Im checking if request.user.is_staff or not – Peter Jul 10 '13 at 22:50

4 Answers4

36

"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.

Tom Christie
  • 33,394
  • 7
  • 101
  • 86
  • 2
    If the request is being redirected, make sure the token is being sent on both the initial request and on the subsequent redirected request. – Tom Christie Jul 11 '13 at 05:44
  • "just access request.user to return the authenticated user". docs said same "return Response(content)" but Im already returning my view or whatever I wanna show in api page. how can I return both? – Peter Jul 11 '13 at 21:24
  • wow nevermind I appended 'user': unicode(request.user) and 'auth': unicode(request.auth) with my existing return and its working now. But ya I had to re-rough my request (auth_token), because Im using redirect between templates. thanks everybody :) – Peter Jul 11 '13 at 21:32
4

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)})
elke
  • 1,220
  • 2
  • 12
  • 24
1

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
);
Stefan Musarra
  • 1,429
  • 14
  • 16
0

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)

unlockme
  • 3,897
  • 3
  • 28
  • 42