11

I am trying to implement authentication using django-rest-framework and django-rest-auth by tivix (link to documentation). I created a user using django shell like:

from django.contrib.auth.models import User
user = User.objects.create_user(username='foo', email='foo@bar.com', password='bar')
user.save()

Then According to Documentation I logged in a user using django-rest-auth like (Terminal Command):

curl -X POST -d "username=foo&password=bar&email=foo@bar.com" http://127.0.0.1:8000/rest-auth/login/

and it returned a token and I know the user is authenticated.

Now I signed out using method described in documentation of django-rest-auth and I can still see the token present in the database. Then I logged in again and it returned the same token as key.

So is there any way by which the token changes or better is deleted every time the user logs out. Also there is no mention in documentation if the token itself will expire(delete automatically) after certain time has passed.

If no such thing is possible, how can I delete the token in both cases?

EDIT : LOGIN & LOGOUT CODE

urls.py (main):

url(r'^rest-auth/', include('rest_auth.urls')),

settings.py:

INSTALLED_APPS = [
    ...
    'rest_framework',
    'rest_framework.authtoken',
    'rest_auth',
    ...
]

Login CURL Command: (GIVEN ABOVE). Login Command Response:

{u'key': u'e41f0a1c2f5e55569df1c41d1d5d4efb77beddee'}

Logout CURL Command:

curl -X POST -d "key=e41f0a1c2f5e55569df1c41d1d5d4efb77beddee" http://127.0.0.1:8000/rest-auth/logout/

Logout Response:

{u'success': u'Successfully logged out.'}
Vini.g.fer
  • 11,639
  • 16
  • 61
  • 90
Manish Gupta
  • 4,438
  • 18
  • 57
  • 104
  • Have you tried `user.auth_token.delete()`? – Håken Lid Jun 10 '16 at 10:03
  • @HåkenLid for that i have to have access to user object. I am directly providing login url in angular app as it returns the tokens and same for logout. So it is using packages predefined view. – Manish Gupta Jun 10 '16 at 10:09
  • How do you sign out? Can you show code and response? The api view endpoint should result in the token getting deleted. – Håken Lid Jun 10 '16 at 10:14
  • You must authenticate using the token when signing out. I'm not sure why the permissions is `AllowAny`, but it looks like the view does not return a error status even if the user is not signed in. https://github.com/Tivix/django-rest-auth/blob/v0.7.0/rest_auth/views.py#L55 – Håken Lid Jun 10 '16 at 10:20
  • @HåkenLid I am passing the token in data while sending the logout POST request. Also I added the url and curl requests for login and logout. – Manish Gupta Jun 10 '16 at 10:28
  • In [the docs](http://django-rest-auth.readthedocs.io/en/latest/api_endpoints.html#basic) it looks like you should post `token` instead of `key` : `curl -X POST -d "token=e41f0a1c2f5e55569df1c41d1d5d4efb77beddee" http://127.0.0.1:8000/rest-auth/logout/` – Håken Lid Jun 10 '16 at 10:39
  • That's not the question, I pretty have the same for my app, wonder how to set expiration time for Tokens. – Maxime B Jun 10 '16 at 10:42
  • @HåkenLid I tried that too but i am still unable to delete the token. – Manish Gupta Jun 10 '16 at 10:44

1 Answers1

20

You have to be logged in to delete the Token.

Here is how django-rest-auth handle log out (ref):

def post(self, request):
    return self.logout(request)

def logout(self, request):
    try:
        request.user.auth_token.delete()
    except (AttributeError, ObjectDoesNotExist):
        pass

    logout(request)

    return Response({"success": _("Successfully logged out.")},
                    status=status.HTTP_200_OK)

So to logout :

curl -X POST -H "Authorization: Token <token>" http://127.0.0.1:8000/rest-auth/logout/

Please note that django-rest-auth support session based and DRF Token Authentication.

Here is doc about DRF Token Authentication and how to use it

Edit

Added info about DRF Token Authentication

varnothing
  • 1,269
  • 1
  • 17
  • 30
  • This seems correct. What I find confusing is that the logout view returns status 200 OK, when the authentication actually didn't succeed. There's a relevant issue on the django-rest-auth github repo [Why logout endpoint doesn't require authorization?](https://github.com/Tivix/django-rest-auth/issues/174) – Håken Lid Jun 10 '16 at 10:59
  • @HåkenLid How can i check if user is logged in after login call? I mean in normal django authentication, I can check by `if user.is_authenticated()`. So how can i check with `django-rest-auth`? I think the user is not getting logged in. That's why the token is not deleted on logout. – Manish Gupta Jun 10 '16 at 11:03
  • @ManishGupta: What was the exact `curl` command, and what was the response? You can use `curl -v` to get more verbose output. – Håken Lid Jun 10 '16 at 11:34
  • 1
    @ManishGupta: Token authentication is different from "logging in". You have to send a valid token with each request. So as long as the client and server have the same token, you are "logged in". To investigate exactly what happens in the `LogoutView`, you can edit `rest-auth/views.py` and add a debugger trace such as `pdb.set_trace()` or logging statements. – Håken Lid Jun 10 '16 at 11:39
  • 1
    @ManishGupta you are right, you are not getting login , as you are sending key in post body. I guess you are not setting Authorization header correctly. You can check if you are logged in or not by hitting /rest-auth/user/ or any protected resource. – varnothing Jun 10 '16 at 11:49
  • @HåkenLid I added checks in the source views.py and i am not getting logged in. Also there is no error i am getting when calling the login function. I added print statements after each statement and there is no error when i send the login command. I couldn't pin point the exact location of error. Do i have add anything to my settings file apart from installed apps? – Manish Gupta Jun 10 '16 at 11:55
  • @electropoet I have to add serializers to settings.py. Only then the authentication header worked. – Manish Gupta Jun 10 '16 at 12:23
  • 4
    I get '{detail: "Successfully logged out."}' but I have not put the token in the header. So what is this method actually doing? I also see the token is still there in the db. – Evan Zamir Jul 30 '17 at 02:22
  • @EvanZamir code block of log out is self-explanatory. Also, note that this endpoint also supports session based authentication. So only if you are logged in either using session, or using authorization headers (token), the token will be deleted. – varnothing Aug 07 '17 at 09:28