You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django中检测用户是否曾完成过身份验证?

Got it, let's work through this problem step by step. You want to check if a Django user has ever authenticated—returning true if they're currently logged in or have logged in before (even if they're logged out now), and only false if they've never logged in at all. You mentioned not wanting to use cookies, so I'll start with a server-side approach first, then cover the cookie method just in case you need it.

Solution 1: Server-Side Tracking (No Manual Cookies)

This approach uses Django's built-in session system and a custom user field to keep track of authentication history securely on the server.

Step 1: Add a Tracking Field to Your User Model

First, we need a way to store whether a user has ever logged in. If you're using a custom user model (highly recommended for Django projects), add a boolean field:

# models.py in your app
from django.contrib.auth.models import AbstractUser
from django.db import models

class CustomUser(AbstractUser):
    has_ever_logged_in = models.BooleanField(default=False)

Don't forget to update your settings.py to use this custom user model:

# settings.py
AUTH_USER_MODEL = "your_app_name.CustomUser"

Then run migrations to apply the change:

python manage.py makemigrations
python manage.py migrate

If you're stuck using Django's default User model, create a Profile model with a one-to-one relationship to User instead:

# models.py
from django.contrib.auth.models import User
from django.db import models

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    has_ever_logged_in = models.BooleanField(default=False)

Step 2: Update the Field on First Login

Use Django's user_logged_in signal to set the has_ever_logged_in field when a user logs in for the first time. We'll also set a session flag so we can track logged-out users who were previously authenticated.

Create a signals.py file in your app:

# signals.py
from django.contrib.auth.signals import user_logged_in
from django.dispatch import receiver
from .models import CustomUser  # Or UserProfile if using default User

@receiver(user_logged_in)
def handle_first_login(sender, user, request, **kwargs):
    # Update the user model field
    if not user.has_ever_logged_in:
        user.has_ever_logged_in = True
        user.save()
    
    # Set a session flag to track logged-out users
    request.session['has_ever_authenticated'] = True

Register the signal in your app's apps.py so Django picks it up:

# apps.py
from django.apps import AppConfig

class YourAppConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'your_app_name'

    def ready(self):
        import your_app_name.signals

Step 3: Check the Authentication History

Now you can write a helper function to check the status anywhere in your code:

def has_ever_authenticated(request):
    # Return true if user is currently logged in
    if request.user.is_authenticated:
        return True
    # Return true if session has the flag (user was logged in before)
    return request.session.get('has_ever_authenticated', False)

In templates, you can check it like this:

{% if user.is_authenticated or request.session.has_ever_authenticated %}
    <!-- User has authenticated before (or is logged in) -->
{% else %}
    <!-- User has never authenticated -->
{% endif %}

Caveat

If a user clears their browser cookies, the session ID is lost, so the session flag will disappear. But if they log in again, the has_ever_logged_in field will still be true, so we'll catch it then.

If you decide to use cookies despite your initial hesitation, here's a secure way to implement it:

Override Django's default login view to set a cookie when the user logs in for the first time:

# views.py
from django.contrib.auth.views import LoginView

class CustomLoginView(LoginView):
    def form_valid(self, form):
        response = super().form_valid(form)
        # Only set the cookie if it doesn't exist already
        if not self.request.COOKIES.get('has_ever_authenticated'):
            response.set_cookie(
                'has_ever_authenticated',
                'true',
                max_age=365 * 24 * 60 * 60,  # Expire in 1 year
                httponly=True,  # Prevent JS access to mitigate XSS
                secure=self.request.is_secure()  # Use secure cookie if using HTTPS
            )
        return response

Update your urls.py to use this custom login view instead of the default:

# urls.py
from django.urls import path
from .views import CustomLoginView

urlpatterns = [
    path('login/', CustomLoginView.as_view(), name='login'),
    # Other URLs...
]

Use this helper function to check the cookie status:

def has_ever_authenticated(request):
    if request.user.is_authenticated:
        return True
    return request.COOKIES.get('has_ever_authenticated') == 'true'

In templates:

{% if user.is_authenticated or request.COOKIES.has_ever_authenticated == 'true' %}
    <!-- User has authenticated before -->
{% else %}
    <!-- User has never authenticated -->
{% endif %}

Caveat

Users can manually delete cookies, which would reset this status. This is less secure than the server-side approach, but it works if you need to track users who clear their sessions but not their cookies.

内容的提问来源于stack exchange,提问作者crimsonpython24

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 17:47:44