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

基于Djoser与JWT的Django认证系统实现是否安全?

Django + Djoser JWT 认证系统的安全问题与改进方案

你的核心担忧完全合理:当前实现中仅靠access token就能创建Django Session的逻辑存在严重安全隐患,一旦token被窃取,攻击者无需密码就能登录用户账号。下面具体分析问题并给出改进方案:

核心风险点

  1. 前端传递用户数据不可信:后端auth视图依赖前端传入的user字段(包含id、username、email)查询用户,前端可随意篡改这些数据,只要携带有效access token,就能登录任意匹配该信息的用户。
  2. JWT与Django Session混合使用冗余且危险:用JWT获取用户信息后再同步创建Django Session,完全没必要,反而引入双重认证冲突和额外攻击面。
  3. Token存储不安全:
    • Access Token存在可读写Cookie中(未设置HttpOnly),XSS攻击可轻易窃取token。
    • Refresh Token同样未设置HttpOnly,一旦被窃取,攻击者可无限刷新获取新的access token。
  4. 前端冗余的token验证流程:每次页面加载都调用verify和authorize接口,既增加服务器负担,又可能让token暴露在更多请求中,提升泄露风险。

具体改进方案

1. 停止混合认证,统一用JWT流程

直接使用Djoser自带的JWT认证能力,放弃手动同步Django Session的逻辑:

  • 所有需要认证的接口,后端通过JWT中间件自动验证请求头或Cookie中的token。
  • 无需前端手动同步用户到Session,后端直接通过request.user获取当前认证用户。

2. 优化Token存储安全

  • Access Token:配置Djoser将其存储在HttpOnly、Secure、SameSite=Strict的Cookie中,前端无法直接读取,避免XSS窃取。
  • Refresh Token:同样存储在HttpOnly的Cookie中,仅允许后端读取和验证,前端只需要在请求返回401时调用刷新接口。

3. 简化前端逻辑

去掉冗余的verify、authorize、auth函数,简化登录和登出流程:

// 登录请求
$.post("/auth/jwt/create/", $(this).serialize())
.done(function() {
    // 后端已将token写入HttpOnly Cookie,直接跳转首页
    window.location.href = "/";
})
.fail(function() {
    alert("登录失败,请检查账号密码");
});

// 登出请求
function logout() {
    $.post("/auth/jwt/logout/", {
        "csrfmiddlewaretoken": $("meta[name='csrf-token']").attr("content")
    })
    .done(function() {
        // 后端清除Cookie后跳转登录页
        window.location.href = "/login/";
    });
}

// 页面加载时无需手动验证token,后端接口会自动处理认证

4. 后端配置与视图优化

配置Djoser与JWT(settings.py)

DJOSER = {
    "LOGIN_FIELD": "username",
    # Access Token Cookie配置
    "JWT_AUTH_COOKIE": "access_token",
    "JWT_AUTH_COOKIE_SECURE": True,
    "JWT_AUTH_COOKIE_HTTPONLY": True,
    "JWT_AUTH_COOKIE_SAMESITE": "Strict",
    # Refresh Token Cookie配置
    "JWT_AUTH_REFRESH_COOKIE": "refresh_token",
    "JWT_AUTH_REFRESH_COOKIE_SECURE": True,
    "JWT_AUTH_REFRESH_COOKIE_HTTPONLY": True,
    "JWT_AUTH_REFRESH_COOKIE_SAMESITE": "Strict",
}

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": (
        "rest_framework_simplejwt.authentication.JWTAuthentication",
    ),
    # 全局配置需要认证的接口,或在视图中单独设置
    "DEFAULT_PERMISSION_CLASSES": (
        "rest_framework.permissions.IsAuthenticated",
    )
}

简化后端视图

废弃原有的auth视图,直接通过JWT中间件获取用户:

from rest_framework.decorators import api_view
from rest_framework.response import Response

@api_view(["GET"])
def user_me(request):
    # request.user由JWT中间件自动验证并填充
    return Response({
        "id": request.user.id,
        "username": request.user.username,
        "email": request.user.email
    })

5. 登出逻辑增强

Djoser默认的JWT登出只会清除前端Cookie,建议额外实现refresh token失效逻辑:

  • 将refresh token存储到数据库中,登出时标记为无效,刷新时检查token有效性。
  • 或设置较短的refresh token有效期,降低被窃取后的风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 20:43:10