This s a question that pops up every once in a while in web site technology discussion forums: if I’m running a web site, what’s the best way to log in as a particular user so that I can see the site as they would see it?
The simplistic thing to do is to somehow get the user’s password, and just log in as them. But this is bad because you should never need to know your users’ passwords, and ideally, you don’t even have access to them.
The better solution is to interpret the classic username and password fields liberally. The username field is always interpreted as the desired username. The clever part comes with the password field: it can either be the user’s password, or it can be a combination of a super-user username and the super-user’s password. It’s the online equivalent of getting access to Joe’s stuff either by showing your identity card proving you are Joe, or by being a policeman and showing your badge.
To make it concrete, imagine authentication is implemented in a function called who_am_i that takes the username and password, and returns the authenticated username, or None. You have an is_password function that can tell you whether a username and password match, and an is_superuser function that can tell you whether a username is a super-user.
Here’s the classic username/password authentication:
def who_am_i(username, password):
"""Determine what user these credentials represent."""
if is_password(username, password):
return username
return None
Here’s the extended version. An @-sign is the separator in the password field for the super-user’s name and password:
def who_am_i(username, password):
"""Determine what user these credentials represent."""
if is_password(username, password):
return username
if '@' in password:
super_name, super_pass = password.split('@', 1)
if is_super(super_name):
if is_password(super_name, super_pass):
return username
return None
I like this solution because it doesn’t require any extra UI, but gives super-users what they need: a way to log in any user they want, without knowing the user’s password. If you like, you can strengthen the super-user path by requiring white-listed IP addresses, or special privilege cookies, etc.
BTW, stackoverflow has more discussion on the same topic, including other (bad) ideas about how to do it (change the user’s password??)
Comments
btw was unable to post a comment in Opera... could be because I was using Opera 10 and not one of the stable releases, though.
(1) If normal user - let me in
(2) If superuser - let me in
If you already have (1) you don't need to check (2). So I suggest: instead of: Or if you want to check for superuser status first (and flick on a superuser bit), do (2) elif (1) instead of (1) elif (2).
http://www.djangosnippets.org/snippets/1590/
Add a comment: