我构建了一个Chrome扩展,将web内容保存到我的Rails应用程序中。最初,只要CORS设置在我的API控制器上打开(参见下面的代码),我就能够依赖现有的Rails/Devise用户会话来确保内容被保存到正确的用户。只要用户登录了,从Chrome扩展到我的站点的AJAX调用就会被正确地验证,无论该扩展是在哪个站点上使用的。
然而,在2020年初,Chrome引入了对它们处理跨站点请求的方式的更改(请参阅
这里
这里
,以及
这里
)。具体地说,cookie的SameSite属性现在将缺省为“Lax”而不是“None”,因此要使用跨站点cookie,cookie设置需要显式设置为
..。
Rails自己的用户会话cookie没有
设置,所以使用Rails会话来验证我的Chrome扩展请求不再是一个选项。
我的解决方法是每当用户登录到应用程序时生成我自己的API身份验证cookie,这确实有必要
已应用。我能够使用这个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
(注意:为了使用选项设置Rails cookie
显然,您需要使用高于2.1.0的机架版本-请参阅:
https://github.com/rails/rails/pull/28297#issuecomment-600566751
)
有人知道发生了什么吗?
发布于 2021-03-02 05:50:54
我仍然不知道为什么跨站cookie突然停止工作,但我是如何破解它的:
解决方法是使用
Chrome扩展cookie API
将我的Rails API身份验证cookie读取到Chrome的本地存储中。由于我们可以在扩展清单中启用对任何特定站点的cookie的访问,因此它们是否是跨站点cookie实际上并不重要。
一旦API cookie被读取到存储中,我们就可以将其作为身份验证令牌与每个请求一起传递,基本上将其用作伪cookie。
因此,完整的流程是用户单击扩展按钮,扩展根据它对该域拥有的显式cookie权限读取API身份验证cookie,如果cookie丢失或过期,它将强制用户登录。如果cookie有效,它将作为身份验证令牌在每个API调用的参数或标头中传递。
关于飞行前选项请求的旁注:
您可能还必须处理使用某些跨站点AJAX发送的OPTIONS飞行前请求(我认为这只是内容类型JSON帖子的问题,但不要引用我的话),因为它们将触发
Rails中的错误。推荐的答案是使用
机架核心
创业板确实解决了这个问题。
请参见:
为什么发送OPTIONS请求,是否可以禁用它-堆栈溢出
*
*
*
如何响应rails-api - Stack溢出中的选项HTTP方法
Rails Responds with 404 on CORS印前检查选项请求-堆栈溢出
执行来自Rails 5的HTTP OPTIONS请求,用于CORS飞行前或其他情况-堆栈溢出
https://stackoverflow.com/questions/63783088
复制相似问题