Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用中间件覆盖Django身份验证_Django_Authentication_Django Middleware - Fatal编程技术网

使用中间件覆盖Django身份验证

使用中间件覆盖Django身份验证,django,authentication,django-middleware,Django,Authentication,Django Middleware,我有一个Django网站和一个MyBB论坛,我想在它们之间共享身份验证。我的网站曾经是一个留言板;然后我在Django中构建了其他几个部分,MyBB和Django都运行在同一个域上。我建立了一个系统,在论坛上注册后,每个用户都有两个用户:一个Django用户和一个MyBB用户。用户使用论坛登录,因此我需要Django读取MyBB的cookies,并将相应的Django帐户设置为登录用户 我可以用中间件来做吗?该中间件将读取MyBB的cookies(其中包含MyBB用户的id),并将request

我有一个Django网站和一个MyBB论坛,我想在它们之间共享身份验证。我的网站曾经是一个留言板;然后我在Django中构建了其他几个部分,MyBB和Django都运行在同一个域上。我建立了一个系统,在论坛上注册后,每个用户都有两个用户:一个Django用户和一个MyBB用户。用户使用论坛登录,因此我需要Django读取MyBB的cookies,并将相应的Django帐户设置为登录用户


我可以用中间件来做吗?该中间件将读取MyBB的cookies(其中包含MyBB用户的id),并将
request.user
设置为相应的Django用户。我是Django新手,我不确定在中间件中设置
request.user
(或调用
authenticate
)是否是个好主意(或者是否有更好的方法)

尝试处理
请求。会话
<代码>请求对象作为视图中的第一个参数出现。有关会话的更多详细信息,请参见此处:


您完全可以使用中间件实现这一点:有关中间件的更多信息,请点击此处:

我认为,中间件和中间件的组合是正确的选择

中间件将调用后端的
authenticate()
,用户id可能作为关键字参数。您的身份验证后端将依次调用相应的
authenticate()
方法并返回一个用户对象

class MiddlewareTracker:
 def process_request(self, request):
    id = request.COOKIES.get('logged_in_id') 
    authenticate(user_id = id)
    return None

class ForumAuthBackend(object):

    def authenticate(self, *args, **kwargs):
        id = kwargs.get('user_id')
        return User.objects.get(id = id)

    def get_user(self, user_id):
        return User.objects.get(id = user_id)

我还建议您仔细检查一下

如果MyBB cookie中存储的用户id代表Django数据库中的同一用户,那么您可以使用默认Django后端直接从该id获取用户对象。如果这些ID不匹配,则需要自定义后端来获取Django用户对象。 要从MyBB cookie获取用户ID并基于它更新用户,您需要有一个自定义的身份验证中间件

中间件

其主要思想是获取用户对象(基于您的身份验证逻辑)并将其分配给request.user。下面是一个示例(未测试)

请记住,对于发送到Django站点的每个请求,都会调用此函数。为了提高性能,您可以缓存用户和/或执行惰性对象技巧

后端

如果需要编写自己的逻辑来获取用户对象和验证用户,可以执行以下操作

class MyBBCookieBackend(object):
    def authenticate(self, user_id):
        return self.get_user(user_id)
    def get_user(self, user_id):
        # if user_id is not the same in Django and MyBB tables, 
        #  you need some logic to relate them and fetch Django user
        try:
            #TODO your custom logic
            user = User.objects.get(id=user_id)
            return user
        except User.DoesNotExist:
            return None

您需要在站点设置文件中添加自定义后端和中间件。

我认为最好使用
process\u view
而不是
process\u request
,因为process view具有以下信息:

  • 请求
  • 要调用的函数
  • 通过的论点

  • 这使得它更加灵活,因为我们还有函数
    信息(view\u func)
    。 因此,我们也可以使用以下方法将其限制为某些函数:

    view_func.__name_
    

    它给出了函数名。

    这对我不起作用。
    authenticate
    调用无效。我已经检查了中间件和授权后端的顺序。我还检查了备份是否返回了有效的
    用户
    对象。是否设置了身份验证?后端是否设置为后端?你能解释一下你所说的认证调用无效是什么意思吗?正在调用它吗?更改为
    request.user=authenticate(user\u id=id)
    ,现在它可以工作了。酷,你能分享你的代码吗?并将问题标记为已回答。要么是我的答案,要么把你的代码作为你的答案张贴出来?几乎是同样的代码,我只是用
    request.user=authenticate(user\u id=id)
    替换了你的
    authenticate
    呼叫。
    process_view(request, view_func, view_args, view_kwargs):
        if not request.user.is_authenticated():
            return HttpResponseRedirect(settings.LOGIN_URL)
        return None
    
    view_func.__name_