Django中的自我验证链接

3 投票
3 回答
1452 浏览
提问于 2025-04-15 21:40

在我的网页应用中,我想给用户发送可以自我验证的链接。这些链接里会包含一个独特的标识符(uuid)。当用户点击这个链接时,链接中的标识符就足够让他们验证身份,他们就不需要输入用户名和密码了。

这样做的最佳方法是什么呢?

3 个回答

0

正如T. Stone所说,普通用户在内部网络环境中非常喜欢分享链接。要是有个系统能自动确认用户身份,那几乎可以肯定会有至少一个人会以别人的身份登录。

当然,还有更好的方法可以通过Cookie信息来更新用户的会话,这样你至少可以大致判断这个用户是否是有效的,并且他们的浏览器也是正常的。这样你会稍微放心一些,因为他们不太可能像分享链接那样随便把自己的电脑借给别人。不过,再次强调,如果你的应用有超过一个用户的话,你现在想做的事情真的是个非常糟糕的主意。

0

从安全的角度来看,这听起来真是个非常糟糕的主意

不过,还是可以做到的。我希望你打算把这个只用在内部系统或者某种公司内部网中。对于一个在线的、真正的网站来说,这可能会引来麻烦。

你可以通过创建一个中间件组件来处理进入的请求。

(虽然没有测试过,但大致思路是这样的)

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

然后你需要设置这个中间件,让它在身份验证和会话中间件之前运行...

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'yourapp.middleware.UUIDQueryStringMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
)

想了解更多关于编码/解码的内容,可以查看这个问题:在Python中加密和解密字符串

我真心希望你不要在一个在线网站上使用这个。

3

如果你正确地设置了链接的过期时间,这个任务是很常见的 :) 你需要自己实现一个认证后端。不是检查用户名和密码,而是要检查 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

把你的后端类添加到后端列表中(在 AUTHENTICATION_BACKENDS 设置里)。

在链接验证的视图中,你应该尝试认证用户,如果成功,就让他/她登录:

user = auth.authenticate(auth_link=link)
if user:
  auth.login(request, user)

撰写回答