Django, request.user is always Anonymous User

后端 未结 9 2058
无人共我
无人共我 2020-12-01 14:57

I am using a custom authentication backend for Django (which runs off couchdb). I have a custom user model.

As part of the login, I am doing a request.user = u

相关标签:
9条回答
  • 2020-12-01 15:08

    After sending Token using Authorization header, the token will be gotten in dispatch function as bellow: '''

    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
    

    So you are using django_role_permission's HasRoleMixin, the dispatch method of this mixin will hide dispatch of the view. I think that the solution is to redefine the mixin of roles-permissions

    0 讨论(0)
  • 2020-12-01 15:13

    I had similar problem when I used custom authentication backend. I used field different than the primary key in the method get_user. It directly solved after using primary key which must be number (not 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
    
    0 讨论(0)
  • 2020-12-01 15:14

    Please elaborate. If you are using a custom user model (which is different from a custom user PROFILE model), then you are basically on your own and the django.contrib.auth framework can not help you with authentication. If you are writing your own authentication system and are not using django.contrib.auth, then you need to turn that off because it seem to be interfering with your system.

    0 讨论(0)
  • 2020-12-01 15:14

    I too have custom authentication backend and always got AnonymousUser after successful authentication and login. I had the get_user method in my backend. What I was missing was that get_user must get the user by pk only, not by email or whatever your credentials in authenticate are:

    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
    

    Its easy to miss this line in the docs:

    The get_user method takes a user_id – which could be a username, database ID or whatever, but has to be the primary key of your User object – and returns a User object.

    It so happened that email is not primary key in my schema. Hope this saves somebody some time.

    0 讨论(0)
  • 2020-12-01 15:19
    user = authenticate(username=username, password=password) 
    if user is not None:
       return render(request, 'home.html',{'user_id':user.id})
    
    0 讨论(0)
  • 2020-12-01 15:26

    The request.user is set by the django.contrib.auth.middleware.AuthenticationMiddleware.

    Check 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
    

    Then look at the get_user function in 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
    

    Your backend will need to implement the get_user function.

    0 讨论(0)
提交回复
热议问题