django request.user.is_authenticated returns AnonymousUser 过了一会儿

django request.user.is_authenticated returns AnonymousUser after a while

我对 Django 有疑问authentification/Login。

我可以正常登录,并且可以使用经过身份验证和登录的用户浏览几个页面,直到在某个时候我的 request.user.is_authenticated returns 错误。然后我有一个 AnonymousUser 并且不能再访问用户信息。

这个问题在我的本地主机服务器上不存在,只有在我试用生产服务器时才会发生。我会说这个问题每 50% 的请求都会发生一次,这意味着我有两次机会我的用户在重定向后保持其身份验证。我主页上的 login() 函数在我每次使用它时都能正常工作,所以这意味着问题出现在重定向期间。

我试图找到出错的具体步骤,但我只看到当我重定向到新页面时请求的属性消失了。当我尝试时,请求突然没有任何属性:

for key, value in request.session.items():
    print('{} => {}'.format(key, value))

而它前面的一页会让我 auth_user_id、auth_user_backend 和 auth_user_hash。

在我最近尝试使用 allauth 实施 Facebook 身份验证之前,我的设置过去一直运行良好。我很难得到它 运行ning,我怀疑这可能导致了当前的问题。我已经删除了与 facebook 登录相关的每一行,但我仍然无法将我的生产服务器设置为 运行.

这是我的settings.py

AUTH_USER_MODEL = 'custom_user.CustomUser'

INSTALLED_APPS = [
    'django.contrib.sites',
    'django.contrib.admin.apps.SimpleAdminConfig',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'debug_toolbar',
    'custom_user.apps.CustomUserConfig',
    'user_profile',
    'rest_framework',
    'django_email_verification',
]

MIDDLEWARE = [
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'debug_toolbar.middleware.DebugToolbarMiddleware',
]

AUTHENTICATION_BACKENDS = [
 'django.contrib.auth.backends.ModelBackend',
]

LOGIN_REDIRECT_URL = '/'

我的登录表单如下所示:

class UserLoginForm(forms.Form):
    email = forms.CharField(widget=forms.TextInput(attrs={'placeholder':'Email or Username', 'size':40}))
    password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder':'Password', 'size':40}))

    def clean(self, *args, **kwargs):
        email = self.cleaned_data.get('email')
        password = self.cleaned_data.get('password')

        if email and password:
            user = authenticate(email=email, password=password)
            if not user:
                ##Maybe the user tried to log in with the email address instead
                try:
                    look_up_user = CustomUser.objects.get(email=email)
                    user = authenticate(email=look_up_user.email, password=password)
                except:
                    raise forms.ValidationError('This user is not recognized')
            if not user.check_password(password):
                raise forms.ValidationError('The Password is incorrect')
            if not user.is_active:
                raise forms.ValidationError('This user is not active')
        return super(UserLoginForm, self).clean(*args, **kwargs)

这是登录视图:

def login_view(request):
    next = request.GET.get('next')
    form = UserLoginForm(request.POST or None)
    if form.is_valid():
        email = form.cleaned_data.get('email')
        password = form.cleaned_data.get('password')
        user = authenticate(email=email, password=password)
        login(request, user)
        if request.user.is_authenticated:
            return redirect('/Market/')
        elif next:
            return redirect(next)
        else:
            return redirect('/')
    context = {
            'form':form,
            "title":"sign-up"
    }
    return render(request, "home.html", context)

一旦用户被识别,我的页面逻辑如下:

def my_view(request):
      if request.user.is_authenticated:
            user = request.user
            ##PAGE LOGIC##
            return render(request, 'path_to.html', context)
      else:
            print("User not authenticated. Redirecting User to login page")
            return redirect('/')

注意:我的用户模型是定制的,但我没有为它调整中间件或 authentification_backend。这可能是我的产品服务器注销我的原因吗?如果是这样,为什么它会在本地主机上工作?

非常感谢您的帮助。

来自 pythonanywere.com 论坛的 Glenn 找到了问题的根源。

我将我的会话存储在缓存中,但我没有使用 memecached 后端。将我的会话存储在那里导致了问题,因为任何中继请求的新工作人员都无法访问缓存的会话。

我的授权可以正常工作,直到使用新的工作人员,然后我就会失去我的授权。

问题已通过更改解决:

SESSION_ENGINE = 'django.contrib.sessions.backends.cache'

至:

SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'