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

  1. 写一个定制的decorator ,比如这snippet个,然后用它来代替
  2. 通过Ajax调用调用base_site内部的自定义身份验证方法.在每个页面上都会进行判断,如果cookie存在并且有效,则用户将自动登录.
  3. LOGIN_REDIRECT_URL页面添加一些javascript,它将在Ajax调用中判断/验证cookie,如果cookie通过身份验证,则自动重定向回引用.

有没有我错过的 Select ?理想情况下,有一种方法可以将其构建到login_required中,而无需编写自定义装饰程序.

推荐答案

在搜索代码之前,请确保已阅读文档.http://docs.djangoproject.com/en/1.2/topics/auth/#other-authentication-sources个 还要阅读提供的Django源代码.

您想要创建三个东西.

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

  2. 用于查找用户的身份验证后端.这是一个存根.它所做的一切就是根据需要创建用户.您的身份管理器将提供详细信息.您只是在Django的本地DB上缓存用户的当前版本.

这是中间件(编辑后).

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

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

为了确保这一点,我们实际上从我们的

请注意,中间件针对每个请求运行.有时,可以将令牌传递给backed authenticate方法.如果令牌存在于本地用户数据库中,则可以在不联系身份管理器的情况下继续请求.

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

这不是我们的活动代码(它有点太复杂,很难做出好的示例.)

Django相关问答推荐

Django项目陷入登录页面

Django BooleanField如何使用RadioSelect?

在生成的表单元素处出现多值DictKeyError

在Python中向函数的查询列表添加条件

SQLite上可以正常使用Many2Many链接注释,但MariaDB上无法正常使用(生产环境)

Django 相当于子查询

包含资源时,DRF 返回我的软删除记录

django REST 框架 - 嵌套 ModelSerializer 的有限查询集?

在 Bootstrap 中使单击的选项卡处于活动状态

如何使用自定义 AdminSite 类?

在 Django 中注册用户的最佳方法

在 docker 容器中创建 django 超级用户而不输入密码

settings.DATABASES 配置不正确使用 django 1.4 执行 syncdb 时出错

如何在保存之前更改 Django 表单字段值?

Django将HttpResponseRedirect返回到带有参数的url

如何在 django 中捕获UNIQUE constraint failed404

如何使 Django 表单字段仅包含字母数字字符

如何使 Django 的开发服务器公开?

Django Rest Framework 序列化程序中的循环依赖

获取'str'对象在Django中没有属性'get'