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/'; } }); }
三、后端配置与视图检查
- DRF全局配置:在
settings.py中确保认证和权限类正确配置:REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_simplejwt.authentication.JWTAuthentication', ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', # 默认要求登录才能访问API ] } - 用户列表视图:确保视图继承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) - 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
相关产品推荐
相关产品推荐

