部署在Render.com的Django在Safari登录时未设置Sessionid Cookie
问题描述
我将Django后端部署在render平台,已在settings.py中完成CSRF与Session规则配置,代码如下:
SECURE_HSTS_SECONDS = 31536000 SECURE_HSTS_INCLUDE_SUBDOMAINS = True SECURE_HSTS_PRELOAD = True SESSION_ENGINE = "django.contrib.sessions.backends.db" SESSION_COOKIE_AGE = 1209600 # 2 weeks SESSION_COOKIE_SECURE = True SESSION_COOKIE_SAMESITE = "None" SESSION_COOKIE_HTTPONLY = True CSRF_COOKIE_SECURE = True CSRF_COOKIE_SAMESITE = "None" CSRF_TRUSTED_ORIGINS = [ "http://localhost:5173", config("LOCAL_SERVER"), config("FRONTEND_URL"), config("BACKEND_URL"), ]
登录请求返回200状态码,但Safari及移动浏览器中Cookie未存储sessionid,导致用户实际未登录;而Brave浏览器可正常完成登录。以下是Django的登录视图代码:
@csrf_protect @api_view(["POST"]) @permission_classes([AllowAny]) def login_view(request): username = request.data.get("username") password = request.data.get("password") user = authenticate(username=username, password=password) if user is not None: login(request, user) csrf_token = get_token(request) if request.data.get("favorites") or request.data.get("cart"): request.user = user # Call sync function with the cookie data sync_user_data(request) response = JsonResponse({"message": "Login success"}, status=status.HTTP_200_OK) response.set_cookie( "sessionid", request.session.session_key, httponly=True, secure=True, samesite="None", domain=config("ALLOWED_HOST_BACKEND"), max_age=1209600, ) response.set_cookie("csrftoken", csrf_token, httponly=True) return response else: return JsonResponse( {"message": "Invalid credentials"}, status=status.HTTP_400_BAD_REQUEST )
前端调用后端API的登录函数:
const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); try { const response = await axiosInstance.post( "/auth/login/", { username, password, }, { headers: { "X-CSRFToken": csrfToken, }, } ); if (response.status === 200) { alert("Login successful!"); // reload the page after login window.location.reload(); } } catch (err) { console.error("Login error:", err); setError("Invalid username or password."); } };
问题原因
- 重复设置sessionid Cookie:Django的
login()函数已经自动为响应生成并设置sessionid Cookie,你在视图中又手动调用response.set_cookie("sessionid", ...)重复设置。Safari等浏览器对重复Cookie的处理更严格,会直接拒绝存储,而Chrome系的Brave兼容性更强,能接受该重复操作。 - CSRF Cookie属性不完整:手动设置csrftoken时未指定
samesite="None"和secure=True,Safari要求跨域Cookie必须同时满足这两个条件,否则会触发隐私策略拦截,拒绝存储该Cookie。 - Domain配置不匹配:如果
ALLOWED_HOST_BACKEND配置的域名与前端请求的域名不匹配(比如一个带www前缀一个不带),或者跨域场景下Domain设置不符合浏览器规则,会导致Safari拒绝存储sessionid Cookie。 - Axios未开启跨域Cookie支持:前端Axios请求未配置
withCredentials: true,跨域场景下浏览器默认不会携带或存储Cookie。Brave可能在某些宽松模式下允许该操作,但Safari严格遵循跨域规则,必须显式开启该配置才能处理Cookie。
内容的提问来源于stack exchange,提问作者Naing
相关产品推荐
相关产品推荐

