Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django login without authenticating

Tags:

django

I have a Django app where there are 2 use cases where I want a user to be able to login without a password.

  1. User registers and gets activation link in e-mail.
  2. User resets password and gets link to change password form in e-mail.

The links include a one-time-use key that I validate, and then I want to log the user in without using credentials.

# This raises an exception unless
# I call user.authenticate 1st.
auth.login(request, user)

How do I acheive this?

like image 239
limscoder Avatar asked Sep 27 '10 20:09

limscoder


2 Answers

You can use the method described here in the Django docs. You grab your user based on the one-time-use key you supplied them and call login(request, user). The catch here is that you'll need to manually specify the authentication backend because you're not calling authenticate() first.

from django.contrib.auth import login

def my_view(request):

    // your user retrieval code
    ...

    user.backend='django.contrib.auth.backends.ModelBackend'
    login(request, user)
like image 63
supersighs Avatar answered Sep 30 '22 12:09

supersighs


You can write your own authentication backend(s) which handles your two use cases. See the docs on writing and using a custom auth backend: http://docs.djangoproject.com/en/1.2/topics/auth/#other-authentication-sources

EDIT: There seems there might be some misconception about how difficult it might be to write your own auth backend. From the docs:

An authentication backend is a class that implements two methods: get_user(user_id) and authenticate(**credentials).

That's right. It's any class that implements two functions both which return User objects.

The get_user method takes a user_id -- which could be a username, database ID or whatever -- and returns a User object.

...authenticate should check the credentials it gets, and it should return a User object that matches those credentials, if the credentials are valid. If they're not valid, it should return None.

The OP has already stated that the links contain one-time keys that he validates (and presumably has associated with the user he wishes to log in). In other words he's already written the business logic for the backend, he would just need to convert it into an appropirate class.

Custom authentication backends can do a number of awesome things in Django 1.2 like object level permissions but they don't have to be that complicated. Plus they stack so you can mix in your token based authentication with the default model backend or OpenID or Facebook. But in the end an auth backend is just class with two methods and I don't see how you can call that overkill.

like image 39
Mark Lavin Avatar answered Sep 30 '22 10:09

Mark Lavin