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

Django中如何要求已登录用户确认密码后才可访问特定页面

Django 仪表盘每次访问密码验证实现方案

核心逻辑是在现有登录验证的基础上,新增一层仪表盘专属的校验逻辑:每次访问仪表盘路由时,检查Session中是否存在自定义的「仪表盘已验证」标记,无标记则跳转至密码验证页面,校验当前登录用户的登录密码,验证通过后再写入标记放行。


步骤1:新建密码校验表单

仅需要密码字段,校验逻辑直接调用Django自带的用户密码校验方法即可:

# your_app/forms.py
from django import forms

class DashboardPwdVerifyForm(forms.Form):
    password = forms.CharField(widget=forms.PasswordInput, label="请输入登录密码")

    def __init__(self, *args, **kwargs):
        self.current_user = kwargs.pop('user', None)
        super().__init__(*args, **kwargs)

    def clean_password(self):
        input_pwd = self.cleaned_data.get('password')
        if not self.current_user.check_password(input_pwd):
            raise forms.ValidationError("密码错误,请重新输入")
        return input_pwd

步骤2:实现密码验证视图

# your_app/views.py
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from .forms import DashboardPwdVerifyForm

@login_required
def dashboard_verify(request):
    # 已经验证过直接跳转仪表盘
    if request.session.get('dashboard_verified', False):
        return redirect('dashboard')
    
    if request.method == 'POST':
        form = DashboardPwdVerifyForm(request.POST, user=request.user)
        if form.is_valid():
            # 验证通过写入Session标记,可自定义有效期,示例设为10分钟(600秒)
            request.session['dashboard_verified'] = True
            request.session.set_expiry(600)
            # 跳转至用户原本要访问的仪表盘地址
            next_url = request.GET.get('next', 'dashboard')
            return redirect(next_url)
    else:
        form = DashboardPwdVerifyForm(user=request.user)
    return render(request, 'dashboard_verify.html', {'form': form})

步骤3:编写验证页模板

<!-- templates/dashboard_verify.html -->
<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">确认验证</button>
    {% for error in form.errors.values %}
        <p style="color: #ff4444;">{{ error.0 }}</p>
    {% endfor %}
</form>

步骤4:给仪表盘加校验逻辑

两种方案按需选择即可:

方案A:自定义装饰器(适合少量仪表盘视图)

先写装饰器:

# your_app/decorators.py
from django.shortcuts import redirect

def need_dashboard_verify(view_func):
    def wrapper(request, *args, **kwargs):
        if not request.session.get('dashboard_verified', False):
            return redirect(f'/dashboard/verify/?next={request.path}')
        return view_func(request, *args, **kwargs)
    return wrapper

给仪表盘视图加装饰器:

@login_required
@need_dashboard_verify
def dashboard(request):
    # 你的仪表盘业务逻辑
    return render(request, 'dashboard.html')

方案B:中间件(适合所有/dashboard开头的路由都要校验的场景)

编写中间件:

# your_app/middleware.py
from django.shortcuts import redirect

class DashboardVerifyMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        path = request.path
        # 排除验证页本身,避免死循环
        if path.startswith('/dashboard/') and path != '/dashboard/verify/':
            if request.user.is_authenticated and not request.session.get('dashboard_verified', False):
                return redirect(f'/dashboard/verify/?next={path}')
        return self.get_response(request)

在settings.py中注册中间件,注意要放在SessionMiddleware和AuthenticationMiddleware之后:

MIDDLEWARE = [
    # 其他默认中间件
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    # 新增你的中间件
    'your_app.middleware.DashboardVerifyMiddleware',
]

步骤5:配置路由

# your_app/urls.py
from django.urls import path
from . import views

urlpatterns = [
    # 其他路由
    path('dashboard/verify/', views.dashboard_verify, name='dashboard_verify'),
    path('dashboard/', views.dashboard, name='dashboard'),
]

注意:如果需要严格实现「每次访问都必须输密码验证」,直接去掉Session中dashboard_verified标记的写入逻辑即可,不过该场景用户体验较差,一般建议设置5-15分钟的验证有效期平衡安全性和使用体验。

内容的提问来源于stack exchange,提问作者R-Cilia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 06:06:09