views:

222

answers:

2

How can I let users log in to my Django site just by clicking a link?

I send out weekly emails asking my users to update information, and I would love to let them log in just by clicking a link.

I have seen this on other sites (like Squarespace), but has anyone done this with Django before?

+2  A: 

Just log them in in the view. You'll have to compensate for the lack of an authenticate() call, but you can just look at the source and figure out what needs doing.

Ignacio Vazquez-Abrams
+2  A: 

I wouldn't recommend attempting to log users in via a url. The url is unencrypted (unless you're using HTTPS and even that can still be scraped) and easy to intercept or just guess with brute force.

There are two possible solutions I can think of:

Use Django Sessions and Cookies

Take advantage of the fact that in Django the login automatically saves a cookie. Once a user is logged in, they stay logged in until they log out (or the cookie expires, but this can be set to live forever). Then, all you need to do is create a /myprofile/ url of some sort and just send the users there. If the user is logged in, this is where you show their user profile.

Encode with a Hash

However, if you really want to actually pass a url with a username and password, I'd recommend obfuscating their username and password as an MD5 hash, which you can then pass via the url.

import urllib, hexlib

username = 'joeblow'
password = 'password'

url = 'http://www.mysite.com/users/login/'
url += urllib.urlencode({
        'username':hashlib.md5(username.lower()).hexdigest(),
        'password':hashlib.md5(password.lower()).hexdigest(),
    })
# return the url to the user in the email template
return url

Note: I would still highly recommend option 1!

Soviut
Why use the username and password at all? I think he should add an extra field to his user model. This field holds a hash. When he sends out the emails he just needs to add this hash to the url. The view that handles the url could look up the corresponding user in the database. To avoid brute forcing I would use a long hash. But even then this method has some security pit falls.
Jens
I wouldn't pass the username or password in URL (obfuscated or not), but I would create an extra field to my UserProfile model with a hash of some sort. I would use this hash to identify the user and call login()Thanks for the advice both Soviut and Jens
tkalve
Good point. I was just giving him suggestions on what *could* be used to seed the hash.
Soviut