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

部署在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 21:04:57