79

I want to create a login api (or use an existing one if it is already pre-bundled) using django rest framework. However, I'm completely at a loss. Whenever I send a post request to the django rest framework "login" url, it just sends back the browsable api template page...

MY CONFIGURATION

urls.py

url(r'^api/v1/', include('rest_framework.urls', namespace='rest_framework'))

settings.py

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

WHAT I WANT

Request:

POST /api/v1/login  username='name' pass='pass'

Response:

200 OK "{username: 'name', 'userId': '54321'}" set-cookie: sessionid="blahblah"
6
  • I am planning to just roll out the api using https and basic auth. But does the browser have a secure way of storing the auth credentials? I don't want the users to have to constantly re-login if they browse away and then browse back to my site. I want to do away with session authentication because of csrf tokens... They are brutal to manage in an API. I want to have my cake and eat it to... Commented Jan 23, 2014 at 19:50
  • Assuming the browser offers a persistent storage binned by domain that only the owner domain can access, I think I could just store session id in the persistent storage and not in the cookie to prevent CSRF vulnerabilities in my API based website. Commented Jan 23, 2014 at 19:53
  • 6
    Did you find out how to do it? Commented May 15, 2014 at 19:35
  • 5
    For future readers, I made a tutorial on the subject: michaelwashburnjr.com/django-user-authentication Commented Nov 15, 2017 at 20:35
  • @mdw7326, "Page not found." it's for your tutorial Commented Apr 22, 2021 at 13:34

4 Answers 4

37

Take a look at the api view from django-rest-framework-jwt. It's an implementation for creating auth tokens rather than cookie sessions, but your implementation will be similar. See views.py and serializers.py. You can probably use the serializers.py unchanged, and just adjust your views to return the right parameters and possibly set the session cookie (can't recall if that's already performed in authentication).

Sign up to request clarification or add additional context in comments.

Comments

14

If you want something like this I do the same thing however I use Token authentication.

Check out their token page here

This may not be what you want but the way I do it is (since I'm using it as a rest api endpoints for mobile clients)

I can do my url localhost:8000/api/users/ -H Authorization : Token A browser could then use the regular login page that you create at the provided rest framework url

url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')

and to get tokens for 'login-less' navigation

url(r'^api-token-auth/', 'rest_framework.authtoken.views.obtain_auth_token')

Then if you make calls and such you can pass the authorization tokens. Of course this is just how I do it and it's probably not the most efficient way but my goal was to create a way that I can provide users with session authentication for browsers and mobile access via tokens.

Then in your views.py make sure you add the authentication requirements for that view. Almost the same as session authentication section

permission_classes = (permissions.IsAdminUser,)

but also include

authentication_classes = (authentication.TokenAuthentication,)

I hope this helps but if not, good luck on your search.

2 Comments

I'm using django rest framework token auth, and I get the token after providing the username/password, but I also would like to receive the user_id ( the pk of the user) along with the token, so I can save in a localStorage and work with that id when needed within the mobile app. What's the correct way to obtain the users primary key when requesting a token?
Check out the above comment with the serializers.py. You may be able to add a pk return field. If that is what you are looking for.
14

Of course token is a good way to authenticate, but questioner is asking about session authentication.

Request:

POST /api/v1/login  username='username' password='password' 
  • Put csrftoken value at X-CSRFToken in header
  • Even though someone using email as username filed, username name parameter is required for email input (e.g. username='[email protected]')

Response:

302 FOUND sessionid="blahblah"
  • If you not specified next value, it will automatically redirect into /accounts/profile/ which can yield 404 error

2 Comments

but how i can implement case with SessionAuthentication lib ? i try but all the time session not save, and whenever i enter a new url after login i get AnonymousUser instead of the saved session
Where does one get the csrftoken to put in the header in this approach? Is there a separate endpoint where we use a GET request for a token, or should we add GET functionality to our "/api/v1/login" endpoint? Or am I missing something? Thank you for your answer it is the only one I could find actually answering the question!
0

Adding our views:

from rest_framework_jwt.views import refresh_jwt_token

urlpatterns = [
    ...
    url(r'^rest-auth/', include('rest_auth.urls')),
    url(r'^rest-auth/registration/', include('rest_auth.registration.urls')),
    ...
    url(r'^refresh-token/', refresh_jwt_token),
]

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.