Django跨应用重定向时如何向客户端传递JWT?
核心问题是302重定向时浏览器不会自动保存响应头中的Authorization字段,因此换用HttpOnly Cookie存储JWT是最优方案——既满足重定向需求,又保证安全性,无需修改现有技术选型和重定向逻辑。
1. 修改登录视图,将JWT存入Cookie
把原代码中设置Authorization头的逻辑替换为设置HttpOnly Cookie:
def loginUser(request: HttpRequest): """ Request : URL : /user/loginUser/ Method : POST Content-type : application/x-www-form-urlencoded Required informations : -username -password Response : Status : 302 Redirect url : /home """ if request.method != "POST": return JsonResponse( data={"error":"Bad request method."}, headers={"Allow":"POST"}, # 修正原代码拼写错误 status=405, ) try: username = request.POST["username"] password = request.POST["password"] except KeyError: return redirect("/user/loginPage/?error=Missing informations") user = authenticate(username=username, password=password) if user != None: exp = datetime.datetime.now() + datetime.timedelta(hours=3) exp = int(exp.timestamp()) payload = { "user_id":user.id, "username":user.username, "exp":exp } token = jwt.encode(payload=payload, key=JWT_KEY) # 改用redirect快捷方法构建响应,设置Cookie response = redirect("/home") response.set_cookie( key="jwt_token", value=token, httponly=True, # 禁止前端JS读取,防范XSS攻击 secure=True, # 仅HTTPS下传输,生产环境必须启用 max_age=3*3600, # 与JWT过期时间保持一致(3小时) path="/", # 全站可访问,可根据实际需求缩小范围 samesite="Lax" # 防范CSRF,跨域场景可调整为None(需配合Secure) ) return response else: return redirect("/user/loginPage/?error=Bad identifiers")
2. 后续请求的JWT验证逻辑调整
目标应用的视图或中间件需要从Cookie中提取JWT进行验证,示例中间件如下:
import jwt from django.http import JsonResponse from django.conf import settings from django.utils.deprecation import MiddlewareMixin class JWTAuthMiddleware(MiddlewareMixin): def process_request(self, request): # 排除无需认证的路径(根据实际情况调整) exempt_paths = ["/user/loginPage/", "/user/loginUser/", "/home"] if request.path in exempt_paths: return token = request.COOKIES.get("jwt_token") if not token: return JsonResponse({"error": "Unauthorized"}, status=401) try: payload = jwt.decode(token, settings.JWT_KEY, algorithms=["HS256"]) # 将用户信息绑定到request对象,供后续视图使用 request.user_id = payload["user_id"] request.username = payload["username"] except jwt.ExpiredSignatureError: return JsonResponse({"error": "Token expired"}, status=401) except jwt.InvalidTokenError: return JsonResponse({"error": "Invalid token"}, status=401)
关键优势
- 安全性:HttpOnly Cookie避免了XSS攻击风险,远优于URL参数传递令牌。
- 兼容性:重定向时浏览器自动携带Cookie,目标应用可直接读取验证,无需前端额外处理。
- 一致性:保留了原有的重定向逻辑和JWT技术选型,无需破坏代码结构。
内容的提问来源于stack exchange,提问作者Killian Jallais
相关产品推荐
相关产品推荐

