【问题标题】:Token Based Authentication in DjangoDjango中基于令牌的身份验证
【发布时间】:2011-06-28 18:26:34
【问题描述】:

我正在尝试找出在我的 django 应用程序中实现基于令牌的身份验证的最佳方法。一个外部的非 django 应用程序正在设置一个带有令牌的 cookie,我有一个可以根据该令牌检索用户信息的 Web 服务。如果用户设置了 cookie,他们不需要在我的网站上进行身份验证,并且应该根据 Web 服务传回的信息自动登录。在我看来,有几个不同的选项可以执行实际检查,我不确定哪个是最好的:

  1. 编写一个像snippet 中的自定义装饰器并使用它来代替 login_required
  2. 通过 ajax 调用调用 base_site 内的自定义身份验证方法。在每个页面上,都会进行检查,如果 cookie 存在且有效,则用户将自动登录。
  3. LOGIN_REDIRECT_URL 页面添加一些javascript,以检查/验证ajax 调用中的cookie,如果cookie 已通过身份验证,则自动重定向回引荐来源网址。

有没有我遗漏的选项?理想情况下,有一种方法可以将其构建到 login_required 中,而无需编写自定义装饰器。

【问题讨论】:

    标签: django


    【解决方案1】:

    在搜索代码之前,请务必阅读文档。 http://docs.djangoproject.com/en/1.2/topics/auth/#other-authentication-sources 另请阅读提供的 Django 源代码。

    你想创造三样东西。

    1. 用于捕获令牌的中间件。这是大部分工作发生的地方。它检查令牌,对其进行身份验证(通过身份管理器确认),然后登录用户。

    2. 用于查找用户的身份验证后端。这是一个存根。它所做的只是根据需要创建用户。您的身份经理有详细信息。您只是在 Django 的本地数据库中缓存用户的当前版本。

    这是中间件(已编辑)。

    from django.contrib.auth import authenticate, login
    
    class CookieMiddleware( object ):
        """Authentication Middleware for OpenAM using a cookie with a token.
        Backend will get user.
        """
        def process_request(self, request):
            if not hasattr(request, 'user'):
                raise ImproperlyConfigured() 
            if "thecookiename" not in request.COOKIES:
                return
            token= request.COOKIES["thecookiename"]
            # REST request to OpenAM server for user attributes.
            token, attribute, role = identity_manager.get_attributes( token )
            user = authenticate(remote_user=attribute['uid'][0])
            request.user = user
            login(request, user)
    

    identity_manager.get_attributes 是我们编写的一个单独的类,用于验证令牌并从 IM 源获取有关用户的详细信息。当然,为了测试目的,必须对此进行模拟。

    这是一个后端(已编辑)

    class Backend( RemoteUserBackend ):
        def authenticate(**credentials):
            """We could authenticate the token by checking with OpenAM
            Server.  We don't do that here, instead we trust the middleware to do it.
            """
            try:
                user= User.objects.get(username=credentials['remote_user'])
            except User.DoesNotExist:
                user= User.objects.create(username=credentials['remote_user'] )
            # Here is a good place to map roles to Django Group instances or other features.
            return user
    

    这不会实质性地改变身份验证或授权的装饰器。

    为了确保这一点,我们实际上从我们的 身份管理器。

    请注意,中间件会针对每个请求运行。有时,可以将令牌传递给支持的 authenticate 方法。如果令牌存在于本地用户数据库中,则无需联系身份管理器即可继续请求。

    但是,我们在身份管理器中有复杂的规则和超时,因此我们必须检查每个令牌以确保其有效。一旦中间件确定令牌有效,我们就可以允许后端进行任何额外的处理。

    这不是我们的实时代码(它有点太复杂,无法作为一个很好的例子。)

    【讨论】:

    • 后端可以简化为用户,_ = User.objects.get_or_create(username=credentials['remote_user'])
    猜你喜欢
    • 2016-01-23
    • 1970-01-01
    • 2015-10-07
    • 2015-10-14
    • 2021-01-25
    • 2016-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多