【问题标题】:http response not setting cookie in the browserhttp响应未在浏览器中设置cookie
【发布时间】:2021-07-20 12:06:04
【问题描述】:

TLDR:

以下response 标头未在浏览器中设置cookie:

Access-Control-Allow-Origin: *
Allow: GET, HEAD, OPTIONS
Content-Length: 7
Content-Type: application/json
Date: Tue, 27 Apr 2021 15:58:02 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.9.4
Set-Cookie: csrftoken=r5r2YcZZvJKs79cbLd24VSyNscpUsxJB6UuWiWO2TXriy6B4r8KDZrwSDyI091K1; expires=Tue, 26 Apr 2022 15:58:02 GMT; Max-Age=31449600; Path=/; SameSite=Lax
Vary: Accept, Cookie, Origin
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

我的request 标头:

Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Cache-Control: no-cache
Connection: keep-alive
Host: 127.0.0.1:8000
Origin: http://localhost:3000
Pragma: no-cache
Referer: http://localhost:3000/
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90"
sec-ch-ua-mobile: ?0
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36

我是 Django 新手,react 和“http header”相关的东西。

我的 django 开发服务器运行在:

http://127.0.0.1:8000/

我的反应开发服务器运行在:

http://127.0.0.1:3000
  1. 要访问该网站,需要登录。因此,通过配置 react-router and following this template,所有未经授权的请求都会首先重定向到登录页面。所以,到目前为止,还没有进行任何 api 调用。
  2. 为了发布登录数据,我需要由服务器设置 csrf 令牌。但由于我没有进行任何 api 调用,我明确创建了一个端点 /api/csrf/ 来设置 csrf 令牌。
# URL: /api/csrf/
class CSRFGet(APIView):
    """
    Explicitly set csrf cookie
    """

    @method_decorator(ensure_csrf_cookie)
    def get(self, request):
        return Response('hello')

useProvideAuth钩子被挂载时,我调用这个端点。

function useProvideAuth() {
    const [token, setToken] = useState(null);

    const login = (username, password) => {
        return axios.post(
            '/auth/',
            {
                username: username,
                password: password
            })
            .then(response => {
                setToken(response.token) 
            })
    }

    useEffect(()=> {
        axios.get(
            '/csrf/'
        )
    },[])

    return {
        token,
        login,
    }
}
  1. 为了检索和设置这个 cookie,我遵循了official Django docs。我还使用 django-CORS-headers allow all origins 启用了 CORS 策略。

现在,当我向任何页面发出请求时,它会重定向到登录页面,我可以看到 api/csrf/ 回复:

Set-Cookie: csrftoken=LgHo2Y7R1BshM4iPisi5qCXhdHyAQK7hD0LxYwESZGcUh3dXwDu03lORdDq02pzG; expires=Tue, 26 Apr 2022 06:29:23 GMT; Max-Age=31449600; Path=/; SameSite=Lax

但是,cookie 根本没有设置。为什么会这样?

我获取 csrf cookie 的方法是否正确?如果我用这种方法制造任何安全漏洞,请告诉我。

【问题讨论】:

    标签: reactjs django cookies django-rest-framework http-headers


    【解决方案1】:

    您能否尝试将以下内容添加到django-cors-headers 配置并重试?

    CORS_ALLOW_CREDENTIALS = 真

    另外,请注意,如果您允许所有来源,上述配置可能不起作用。请参阅此 Mozilla 文档:Credential is not supported if the CORS header ‘Access-Control-Allow-Origin’ is ‘*’

    如果你遇到这样的错误,我建议设置:

    CORS_ALLOWED_ORIGINS = [
        "http://127.0.0.1:3000",
    ]
    

    或者更高级的东西:

    CORS_ALLOWED_ORIGIN_REGEXES = [
           r"^http://127.0.0.1:[0-9]{1,4}$",
    ]
    

    最后,请确保您使用的是 django-cors-headers 版本 >= 3.5,因为当时上述 2 配置具有不同的别名。

    让我知道它是否有效,我很好奇。

    【讨论】:

    • 非常感谢您的帖子!原来问题是,我使用http://127.0.0.1:8000 进行api 调用,而我的服务器在http://localhost:8000 上。意识到这个xD后我笑了。
    • ++ 用于说明CORS_ALLOW_CREDENTIALS = True,我完全忘记了!
    【解决方案2】:

    原来问题是,我使用 http://127.0.0.1:8000 进行 api 调用,而我的服务器位于 http://localhost:8000。因此,hostorigin 在我的 request 标头中与同一个域不匹配。

    cookies可以在同一个域下使用,different portssubdomains,不像Same-Origin policy,但是不能跨域使用。

    就我而言,我猜 http://127.0.0.1:8000http://localhost:8000 被认为是不同的域,因此浏览器没有设置我的 cookie。

    感谢 Anas Tiour 说明 Allow-Credentials。我也试过了,但在我找到真正的原因之前仍然没有运气。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-07
      • 2016-11-19
      • 2019-04-26
      • 1970-01-01
      • 2018-10-26
      • 2014-08-24
      • 2021-09-30
      相关资源
      最近更新 更多