直接用djangorestframework-simplejwt而非手写JWT逻辑,因其已覆盖RFC 7519标准,内置exp/nbf/iat校验、安全刷新及黑名单机制,避免时钟偏移、token_type伪造等高危错误。

为什么直接用 djangorestframework-simplejwt 而不是自己手写 JWT 逻辑?
因为 JWT 签发、校验、刷新、黑名单管理这些环节极易出错——比如时钟偏移未处理导致 token 突然失效,或忘记验证 token_type 字段被攻击者伪造 access token 为 refresh token。官方推荐的 djangorestframework-simplejwt 已覆盖 RFC 7519 标准细节,并内置了 TokenObtainPairView、TokenRefreshView 等安全封装,省去手动处理 exp、nbf、aud 的风险。
安装后只需两步配置就能跑通基础流程:
- 在
settings.py中添加'rest_framework_simplejwt'到INSTALLED_APPS - 将认证类设为
'rest_framework_simplejwt.authentication.JWTAuthentication',并配置DEFAULT_AUTHENTICATION_CLASSES
如何自定义 token payload 添加用户角色或部门信息?
默认的 TokenObtainPairView 只返回 access 和 refresh 字段,但业务常需在 token 中嵌入 role、dept_id 等字段,避免每次请求都查数据库。关键不是改视图,而是重写 token serializer:
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
<p>class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
@classmethod
def get_token(cls, user):
token = super().get_token(user)</p><h1>注意:这里只加非敏感字段,密码、手机号等绝不能放进去</h1><pre class="brush:php;toolbar:false;"> token['role'] = user.profile.role # 假设 profile 是 OneToOne 关联
token['dept_id'] = user.profile.dept_id
return token
然后在 urls.py 中替换默认视图:
from .serializers import CustomTokenObtainPairSerializer from rest_framework_simplejwt.views import TokenObtainPairView <p>class CustomTokenObtainPairView(TokenObtainPairView): serializer_class = CustomTokenObtainPairSerializer </p>
前端传 token 时为什么总报 Invalid token header. No credentials provided.?
这个错误几乎全是请求头格式不对导致的。DRF SimpleJWT 默认要求 header 是 Authorization: Bearer <token></token>,注意三点:
- 必须带
Bearer前缀(后面有个空格),不能只传 token 字符串 - 前端 fetch 或 axios 要显式设置 header,例如:
headers: {'Authorization': 'Bearer ' + token} - 如果用 Postman 测试,Auth 类型选
Bearer Token,别选API Key或手动填 raw header 写错空格
后端也可临时放宽校验(仅调试用):在 settings 中设 SIMPLE_JWT['AUTH_HEADER_TYPES'] = ('Bearer', 'JWT'),支持多前缀,但上线前务必删掉。
refresh token 过期后用户还能自动登录吗?
不能。refresh token 本身也有过期时间(默认 7 天),且一旦用它换过新 access token,旧 refresh token 就立即失效(SimpleJWT 默认启用 ROTATE_REFRESH_TOKENS=True)。这意味着:
- 用户长时间不操作(超过 refresh token 有效期),必须重新输账号密码
- 若想实现“长期免登”,得结合设备指纹 + 安全 cookie 存储 refresh token(需 HTTPS +
HttpOnly+SameSite=Strict),但这是额外架构设计,JWT 层面不负责 - 别把 refresh token 存 localStorage —— XSS 可直接盗取,等于交出长期登录凭证
真正容易被忽略的是:生产环境必须配 SIMPLE_JWT['SIGNING_KEY'] 为强随机密钥,而不是用默认的 SECRET_KEY;否则攻击者拿到任意一个 access token 就能伪造签名,绕过所有校验。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











