In my web app I would like to be able to email self-authenticating links to users. These links will contain a unique token (uuid). When they click the link the token being present in the query string will be enough to authenticate them and they won't have to enter their username and password.
开发者_JAVA百科What's the best way to do this?
That's quite common task if you properly expire your links :) You'll need to implement your own authentication backend. Instead of checking username and password parameters you'll check for auth_link.
class AuthLinkBackend(object):
def authenticate(auth_link = None):
if auth_link:
# validate and expire this link, return authenticated user if successful
return user
Add your backend class to the list of backends (AUTHENTICATION_BACKENDS setting).
In the link validation view you should try to authenticate user and if it succeeded, log in him/her:
user = auth.authenticate(auth_link=link)
if user:
auth.login(request, user)
From a security standpoint, this seems like a really bad idea.
That said, it can still be done. I'm hoping you're planning on using this only on something that would be internal or a company intranet of some sort. For a live, on-the-web, legit website, this is probably just asking for trouble.
You can handle incoming requests by creating a middleware component to do so.
(untested, but the general idea)
import base64
class UUIDQueryStringMiddleware(object):
def process_request(request):
if request.method == 'GET':
if not request.user.is_authenticated():
uuid = request.REQUEST.get('u', None)
if uuid:
username = base64.b64decode(uuid)
try:
user = User.objects.get(username=username)
request.user = user
except:
pass
# Pass the original request back to Django
return request
You would then need to setup this middleware to run before the auth and sessions middleware runs...
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'yourapp.middleware.UUIDQueryStringMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
)
See this question for more details on encoding/decoding: encrypt & decrypt strings in python
I REALLY hope you're not going to use this on a live site.
To T. Stone's point, end users are notorious for passing links around -- ESPECIALLY those in an intraweb environment. Having something that authenticated the user automatically means that I can almost guarantee that you're going to have at least one person logged in as somebody else.
There are better ways, of course, to refresh a user's session from Cookie information, so you at least have a decent idea that they're a valid user attached to a valid browser and can feel SOMEwhat safer in that they aren't likely to hand their laptops about like they might with a link, but yes... to reiterate, what you're trying to do is a VERY bad idea if your app has more than 1 user.
精彩评论