Django 跨域 SameSite 问题(DJango无法获取Chrome的cookie问题)

问题描述

最近一个项目需求:通过iframe嵌入我们的网站实现单点登录。

结果始终登录不成功,F12控制台提示如下信息:

A cookie associated with a cross-site resource at http://x.x.x.x/ was set without the `SameSite` attribute. It has been blocked, as Chrome now only delivers cookies with cross-site requests if they are set with `SameSite=None` and `Secure`. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032.

解决方法

看输出信息,应该是cookie的SameSite属性不正确的问题,但是以前没这个问题啊。最后,经过测试发现,chrome升级到80版本之后,cookie的SameSite属性默认值由None变为Lax。

解决方式如下:

  • 最简单(适合临时调试):设置chrome为禁用samesite。需要每个客户端修改设置,不现实。

    打开链接:chrome://flags/#same-site-by-default-cookies。

    然后搜索:SameSite by default cookies,将default改成disable即可。

  • 修改程序,主动设置SameSite属性。

    Django版本高于2.1,直接设置SESSION_COOKIE_SAMESITE=None即可;

    如果DJango版本低于2.1需要引入库django-cookie-samesite来处理:

    1. 安装django cookies samesite:
    pip install django-cookies-samesite
    
    1. 将中间件添加到中间件类的顶部
    MIDDLEWARE_CLASSES = (
        'django_cookies_samesite.middleware.CookiesSameSite',
        ...
    )
    
    1. 在settings.py中设置首选的samesite策略:
    SESSION_COOKIE_SECURE = True
    SESSION_COOKIE_SAMESITE = 'None'
    

    注:必须同时有secure这个属性才行。是个坑!