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

Django REST Framework中simplejwt+Ajax+模板登录认证问题

解决DRF + SimpleJWT + 模板的认证与授权问题

一、修复登录流程:确保Token获取与跳转逻辑正确

首先要阻止表单默认提交行为,避免页面刷新打断Ajax请求,在请求成功后存储Token再跳转:

  • 修正user_login.html中的Ajax代码:
    $('#login-form').on('submit', function(e) {
        e.preventDefault(); // 禁用表单默认提交
        $.ajax({
            url: '/api/token/', // 用SimpleJWT自带的Token获取接口
            method: 'POST',
            data: $(this).serialize(),
            success: function(res) {
                // 把Token存入localStorage
                localStorage.setItem('access_token', res.access);
                localStorage.setItem('refresh_token', res.refresh);
                // 跳转到用户列表页
                window.location.href = '/user-list/';
            },
            error: function(xhr) {
                alert('登录失败:' + (xhr.responseJSON?.detail || '未知错误'));
            }
        });
    });
    
  • 后端建议直接使用SimpleJWT的TokenObtainPairView,无需自定义UserLoginView,除非有特殊业务需求。如果坚持自定义,务必返回包含access和refresh字段的JSON响应。

二、用户列表页:正确携带Token请求授权API

请求需要授权的DRF接口时,必须在请求头中添加Authorization: Bearer <access_token>:

  • 修正用户列表页的Ajax代码:
    $(document).ready(function() {
        const accessToken = localStorage.getItem('access_token');
        // 无Token则跳转登录页
        if (!accessToken) {
            window.location.href = '/login/';
            return;
        }
    
        $.ajax({
            url: '/api/users/', // 你的用户列表API地址
            method: 'GET',
            headers: {
                'Authorization': `Bearer ${accessToken}`
            },
            success: function(users) {
                // 渲染用户列表到页面(示例:生成表格行)
                const $tbody = $('#user-table tbody');
                $tbody.empty();
                users.forEach(user => {
                    $tbody.append(`<tr><td>${user.id}</td><td>${user.username}</td><td>${user.email}</td></tr>`);
                });
            },
            error: function(xhr) {
                if (xhr.status === 401) {
                    // Token过期,尝试刷新Token后重试
                    refreshToken();
                } else {
                    alert('获取用户列表失败:' + (xhr.responseJSON?.detail || '未知错误'));
                }
            }
        });
    });
    
    // Token刷新逻辑(可选)
    function refreshToken() {
        const refreshToken = localStorage.getItem('refresh_token');
        $.ajax({
            url: '/api/token/refresh/',
            method: 'POST',
            data: { refresh: refreshToken },
            success: function(res) {
                localStorage.setItem('access_token', res.access);
                // 重新加载当前页面或重新发起请求
                window.location.reload();
            },
            error: function() {
                // 刷新失败,跳转登录页
                window.location.href = '/login/';
            }
        });
    }
    

三、后端配置与视图检查

  1. DRF全局配置:在settings.py中确保认证和权限类正确配置:
    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': [
            'rest_framework_simplejwt.authentication.JWTAuthentication',
        ],
        'DEFAULT_PERMISSION_CLASSES': [
            'rest_framework.permissions.IsAuthenticated', # 默认要求登录才能访问API
        ]
    }
    
  2. 用户列表视图:确保视图继承DRF的基类,并设置正确的权限:
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from rest_framework.permissions import IsAuthenticated
    from django.contrib.auth.models import User
    
    class UserListView(APIView):
        permission_classes = [IsAuthenticated]
    
        def get(self, request):
            # 返回用户数据(按需筛选字段)
            user_data = User.objects.all().values('id', 'username', 'email')
            return Response(user_data)
    
  3. URL配置:注册SimpleJWT的接口和你的视图:
    from django.urls import path
    from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
    from .views import UserListView
    from django.views.generic import TemplateView
    
    urlpatterns = [
        # SimpleJWT接口
        path('api/token/', TokenObtainPairView.as_view(), name='token_obtain'),
        path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
        # API视图
        path('api/users/', UserListView.as_view(), name='user_api'),
        # 模板页面
        path('login/', TemplateView.as_view(template_name='user_login.html'), name='login'),
        path('user-list/', TemplateView.as_view(template_name='user_list.html'), name='user_list_page'),
    ]
    

四、排查要点

  • 检查localStorage中的Token是否存在且正确:打开浏览器开发者工具→Application→Local Storage。
  • 检查请求头:在Network标签中查看用户列表API的请求,确认Authorization头是否正确携带。
  • 检查Token有效期:SimpleJWT默认access_token有效期5分钟,refresh_token有效期1天,过期需调用刷新接口。
  • 确认无跨域问题:如果前后端不同域名,需配置django-cors-headers,同域名下可忽略。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 15:54:25