CORs 战 SameSite 的故事
2024-01-29 21:46:32
CORS 和 SameSite 是两个密切相关的 Web 安全概念。CORS(跨域资源共享)允许浏览器向跨域服务器发送请求,而 SameSite 则是一种 HTTP 头,用于指定 Cookie 是否可以跨域发送。
最近,我遇到一个项目,需要在开发环境、测试环境和线上环境中进行跨域请求。一开始,我使用传统的 CORS 解决方法,即在服务端设置 CORS 白名单,并在前端代码中设置 withCredentials。这种方法在开发环境和测试环境中运行良好,但在线上环境中却遇到了问题。
在线上环境中,当我尝试向跨域服务器发送请求时,浏览器会疯狂刷新。我花了很长时间才定位到问题所在:SameSite 属性。
SameSite 属性是一个 HTTP 头,用于指定 Cookie 是否可以跨域发送。SameSite 属性有三个可能的值:
Lax
:Cookie 可以随同跨域请求发送,但只能在GET、HEAD 和 POST请求中发送。Strict
:Cookie 只能随同同源请求发送。None
:Cookie 可以随同任何类型的请求发送。
在默认情况下,SameSite 属性的值为 Lax
。这意味着,如果我在前端代码中设置 withCredentials,浏览器会自动在跨域请求中发送 Cookie。但是,在某些情况下,浏览器可能会阻止发送 Cookie。例如,如果请求的 URL 包含敏感信息,或者如果请求是通过一个不安全的协议(如 HTTP)发起的。
在我的项目中,SameSite 属性的值被设置为 Strict
。这意味着,浏览器不会在跨域请求中发送 Cookie。因此,当我尝试向跨域服务器发送请求时,浏览器会疯狂刷新。
为了解决这个问题,我尝试了两种方法:
- SSR(服务端渲染) :SSR 是一种渲染技术,它允许在服务端渲染 HTML。这意味着,当浏览器请求一个页面时,服务端会先将该页面渲染成 HTML,然后将 HTML 发送给浏览器。这样,浏览器就不需要再向跨域服务器发送请求,从而避免了 SameSite 问题。
- 预渲染 :预渲染是一种渲染技术,它允许在构建时将 HTML 渲染成静态文件。这意味着,当浏览器请求一个页面时,浏览器可以直接从静态文件中获取 HTML,而不必向服务器发送请求。这样,浏览器就不需要再向跨域服务器发送请求,从而避免了 SameSite 问题。
最终,我使用 SSR 技术解决了这个问题。我将项目中的所有页面都渲染成了 HTML,然后将 HTML 文件部署到 CDN 上。这样,当浏览器请求一个页面时,浏览器可以直接从 CDN 上获取 HTML,而不必向跨域服务器发送请求。
通过使用 SSR 技术,我成功地解决了 CORS 与 SameSite 的问题。我希望我的经历能够帮助到其他遇到同样问题的人。