Django,request.user始终是匿名用户

时间:2011-03-21 11:27:19

标签: django

我正在为Django使用自定义身份验证后端(运行在couchdb之后)。我有一个自定义用户模型。

作为登录的一部分,我正在执行request.user = user并在会话中保存用户ID。 但是,在后续请求中,我无法检索request.user。它始终是AnonymousUser。但是,我可以从会话中检索用户ID,并确认正确设置了会话cookie。

我错过了什么?

我不想使用关系数据库,因为我想在couchdb中维护所有用户数据。

编辑:我编写了一个不从Django的auth用户继承的类。但它具有用户名和电子邮件属性。出于这个原因,我的后端不会返回一个派生自auth User的类。

9 个答案:

答案 0 :(得分:11)

request.userdjango.contrib.auth.middleware.AuthenticationMiddleware设置。

检查django/contrib/auth/middleware.py

class LazyUser(object):
    def __get__(self, request, obj_type=None):
        if not hasattr(request, '_cached_user'):
            from django.contrib.auth import get_user
            request._cached_user = get_user(request)
        return request._cached_user

class AuthenticationMiddleware(object):
    def process_request(self, request):
        request.__class__.user = LazyUser()
        return None

然后查看get_user中的django/contrib/auth/__init__.py函数:

def get_user(request):
    from django.contrib.auth.models import AnonymousUser
    try:
        user_id = request.session[SESSION_KEY]
        backend_path = request.session[BACKEND_SESSION_KEY]
        backend = load_backend(backend_path)
        user = backend.get_user(user_id) or AnonymousUser()
    except KeyError:
        user = AnonymousUser()
    return user

您的后端需要实施get_user功能。

答案 1 :(得分:4)

你说你已经编写了一个自定义身份验证后端,但实际上你所编写的是一个完整的自定义身份验证应用程序,它不与Django的contrib.auth接口。

如果要为身份验证数据使用非关系数据库,您需要创建一个提供两种方法的类:get_user(user_id)authenticate(**credentials)。见the documentation。一旦您对用户进行了身份验证,您只需调用Django的常规登录方法即可。应该没有理由手动设置request.user或将任何内容放入会话中。

修改后更新这与它无关。不要求用户类派生自auth.models.User。您仍然只需要定义一个将返回用户类实例的get_user方法。

答案 2 :(得分:4)

我也有自定义身份验证后端,并且在成功身份验证和登录后始终获得AnonymousUser。我的后端有get_user方法。我遗漏的是,get_user必须仅通过pk获取用户,而不是通过电子邮件或authenticate中的任何凭据:

class AccountAuthBackend(object):

@staticmethod
def authenticate(email=None, password=None):
    try:
        user = User.objects.get(email=email)
        if user.check_password(password):
            return user
    except User.DoesNotExist:
        return None

@staticmethod
def get_user(id_):
    try:
        return User.objects.get(pk=id_) # <-- tried to get by email here
    except User.DoesNotExist:
        return None

在文档中很容易错过这一行:

  

get_user方法接受user_id - 可以是用户名,   数据库ID或其他,但必须是您的用户的主键   object - 并返回User对象。

碰巧email不是我架构中的主键。希望这能节省一些时间。

答案 3 :(得分:2)

请详细说明。如果您使用的是自定义用户模型(与自定义用户PROFILE模型不同),那么您基本上是独立的,并且django.contrib.auth框架无法帮助您进行身份验证。如果您正在编写自己的身份验证系统但未使用django.contrib.auth,那么您需要将其关闭,因为它似乎干扰了您的系统。

答案 4 :(得分:0)

使用自定义身份验证后端时,我遇到了类似的问题。我在方法 get_user 中使用了与主键不同的字段。 使用主键后必须直接解决,该主键必须是数字(不是str)

def get_user(self, user_id):
    try:
        return User.objects.get(pk=user_id) # <-- must be primary key and number
    except User.DoesNotExist:
        return None

答案 5 :(得分:0)

使用Authorization标头发送令牌后,令牌将在分配函数中获得,如下所示: '''

def dispatch(self, request, *args, **kwargs):

    self.args = args
    self.kwargs = kwargs
    request = self.initialize_request(request, *args, **kwargs)
    self.request = request
    self.headers = self.default_response_headers  # deprecate?

    try:
        self.initial(request, *args, **kwargs)

        # Get the appropriate handler method
        if request.method.lower() in self.http_method_names:
            handler = getattr(self, request.method.lower(),
                              self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed

        response = handler(request, *args, **kwargs)

    except Exception as exc:
        response = self.handle_exception(exc)

    self.response = self.finalize_response(request, response, *args, **kwargs)
    return self.response

因此,您使用的是django_role_permission的HasRoleMixin,此mixin的dispatch方法将隐藏视图的派发。 我认为解决方案是重新定义角色权限的组合

答案 6 :(得分:0)

user = authenticate(username=username, password=password) 
if user is not None:
   return render(request, 'home.html',{'user_id':user.id})

答案 7 :(得分:0)

在我看来添加了这些

from rest_framework.permissions import IsAuthenticated
from rest_framework.authentication import TokenAuthentication

authentication_classes = (TokenAuthentication,)
permission_classes = (IsAuthenticated,)

并开始获得原始用户

答案 8 :(得分:0)

如果您使用的是 API(Django-rest-framework)并使用get,post等方法访问视图。

您可以通过发送与该用户相对应的 Bearer / JWT令牌来获得该用户。

错误

# prints Anonymous User

def printUser(request):
   print(request.user)

正确

# using decorators 
# prints username of the user 

@api_view(['GET'])  # or ['POST'] .... according to the requirement
def printUser()
    print(request.user)
相关问题