【发布时间】:2020-12-26 04:49:17
【问题描述】:
我构建了一个 Chrome 扩展程序,可以将 Web 内容保存到我的 Rails 应用程序中。最初,只要在我的 API 控制器上打开了 CORS 设置(参见下面的代码),我就能够依赖现有的 Rails/Devise 用户会话来确保将内容保存给正确的用户。只要用户登录,从 Chrome 扩展程序对我的站点的 AJAX 调用就会被正确验证,无论在哪个站点上使用该扩展程序。
不过,Chrome 在 2020 年初对其处理跨站点请求的方式进行了更改(请参阅 here、here 和 here)。具体来说,cookie 的 SameSite 属性现在默认为“Lax”而不是“None”,因此要使用跨站点 cookie,cookie 设置需要显式设置为 SameSite=None; Secure。
Rails 自己的用户会话 cookie 没有 SameSite=None; Secure 设置,因此不再可以选择使用 Rails 会话来验证我的 Chrome 扩展程序的请求。
我的解决方法是在用户登录应用程序时生成我自己的 API 身份验证 cookie,它确实应用了必要的 SameSite=None; Secure。我能够使用这个 cookie 对来自我的 Chrome 扩展程序的 API 调用进行身份验证,一切都很好。
然后在 2020 年 9 月上旬,它突然停止工作。 Rails 不再从 Chrome 扩展请求中读取跨站点 cookie。没有错误或警告,该值为空。
API 控制器:
# This gets called when user logs into app:
def set_cross_site_cookie
# NOTE: Won't work in dev because secure = true
cookies[:foo_cookie] = {
value: 'bar',
expires: 1.year.from_now,
same_site: :none, # Required in order to access from Chrome extension on different site
secure: true # Required in order to access from Chrome extension on different site
}
cookie = cookies[:foo_cookie]
render json: {cookie: cookie}
end
# This SHOULD work when called from our Chrome extension:
def get_cross_site_cookie
# Add headers to allow CORS requests
# SEE: http://stackoverflow.com/questions/298745/how-do-i-send-a-cross-domain-post-request-via-javascript
response.headers['Access-Control-Allow-Origin'] = '*'
response.headers['Access-Control-Request-Method'] = %w{GET POST OPTIONS}.join(",")
cookie = cookies[:foo_cookie]
render json: {cookie: cookie}
end
Rails 5,机架 2.1
(注意:为了使用选项 same_site: none 设置 Rails cookie,您显然需要使用高于 2.1.0 的机架版本 - 参见:https://github.com/rails/rails/pull/28297#issuecomment-600566751)
有人知道发生了什么吗?
【问题讨论】:
-
嘿@Yarin,你能解决这个问题吗?
-
@Simon Yea 想出了一个 hack-在下面为你发布的答案
标签: ruby-on-rails google-chrome cookies google-chrome-extension rack