简体   繁体   中英

Django request.user becomes anonymous after changing page. Using custom user model

I'm using a custom user model that extends AbstractBaseUser . This is the user model:

class cUser(AbstractBaseUser):
    def save(self, *args, **kwargs):
        pass
    role_id = models.IntegerField()
    user_id = models.IntegerField()
    email = models.CharField(max_length=40)
    password = models.CharField(max_length=40)
    f_name = models.CharField(max_length=40)
    l_name = models.CharField(max_length=40)
    address_id = models.IntegerField()
    phone_num = models.IntegerField()
    loan_item_count = models.IntegerField()
    id = models.IntegerField(unique = True, primary_key = True)

    def __init__(self, dictionary, *args, **kwargs):
        self.role_id = int(dictionary['role_id'])
        self.user_id = dictionary['user_id']
        self.email = dictionary['email']
        self.password = dictionary['password']
        self.f_name = dictionary['f_name']
        self.l_name = dictionary['l_name']
        self.address_id = dictionary['address_id']
        self.phone_num = dictionary['phone_num']
        self.loan_item_count = dictionary['loan_item_count']
        self.id = self.user_id

    USERNAME_FIELD = 'user_id'
    class Meta:
        managed = False

I don't want the model to affect the DB in any way. I'm loading it by a simple raw SQL query from a gateway method.

This is how I'm handling login:

def login_request(request):
    if request.method == 'POST':
        form = LoginForm(request.POST)
        if form.is_valid():
            username = request.POST['username']
            password = request.POST['password']
            user = userGateway(username,password)
            if user is not None:
                print("=========USER==========")
                print(user.email)
                user.backend = 'django.contrib.auth.backends.ModelBackend'
                login(request,user)
                print(request.user.is_authenticated)
                if user.role_id==1:
                    return render(request, 'biblioteca/admin/landing.html')
                    # return HttpResponseRedirect('/')
                else:
                    return render(request, 'biblioteca/landing.html')
            else:
                print("=========NOT USER==========")
    else:
        if(request.user is not None and not request.user.is_anonymous):
            return render(request, 'biblioteca/admin/landing.html')
        form = LoginForm()
        return render(request, 'biblioteca/login.html', {'form': form})

As you can see, I'm setting the back-end before login to authenticate without having to pass through a password - the password check is being done when the user object is created by comparing the password passed in with the password retrieved from the DB.

If I return a render , as seen here, the next page contains the proper request.user object. If I return a redirect, it does not. Additionally, if I leave that page at all, the user becomes unauthenticated and anonymous again, losing the session.

Any help as to why this happens would be much appreciated.

When you redirect, the request is completed and a redirect code is sent to the client, who then makes a new request to the new page without the POST data for the login form. The user may not be getting their token. In that case, render a page to log them in that delays for a few seconds, then redirects them to the right spot.

So, this was solved by turning userGateway() into a proper auth backend and implementing it like that.

Explanation as to why:

The sessionID in django stores a hash of the user's PK as well as the auth backend used to log in. Whenever a new request is sent, data needed is lazy-loaded from the DB using this hash.

This is why login() was properly authenticating the user on the login page, because it was pretty much forced to. As soon as another request happened, though, it would be unable to load the user's data from the DB, and would flush the sessionid.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM