微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用跨站点Cookie从Chrome扩展程序发布到Rails API 关于飞行前选项请求的旁注:

如何解决使用跨站点Cookie从Chrome扩展程序发布到Rails API 关于飞行前选项请求的旁注:

我构建了一个Chrome扩展程序,可将网络内容保存到我的Rails应用程序中。最初,只要在我的API控制器上打开了CORS设置,我就能够依靠现有的Rails / Devise用户会话来确保将内容保存到正确的用户。只要用户登录,无论使用该扩展程序在哪个站点上,从Chrome扩展程序到我网站的AJAX调用都将得到正确的身份验证。

但是,在2020年初,Chrome对他们处理跨站点请求的方式进行了更改(请参见hereherehere)。具体来说,cookie的SameSite属性现在认为“宽松”,而不是“无”,因此,要使用跨站点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。没有错误或警告,该值仅为null。

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

第5机架,第2.1机架 (注意:要使用选项same_site: none设置Rails cookie,您显然需要使用高于2.1.0的机架版本-SEE:https://github.com/rails/rails/pull/28297#issuecomment-600566751 >

有人知道发生了什么事吗?

解决方法

我仍然不知道为什么跨站点 cookie 突然停止工作,但我是这样破解它的:

解决方法是使用 Chrome extension cookie API 将我的 Rails API 身份验证 cookie 读取到 Chrome 的本地存储中。由于我们可以在扩展程序清单中启用对任何特定站点的 cookie 的访问,因此它们是否是跨站点 cookie 实际上并不重要。

一旦 API cookie 被读入存储,我们就可以将其作为身份验证令牌与每个请求一起传递,基本上将其用作伪 cookie。

所以完整的流程是用户点击扩展按钮,扩展根据它对该域的显式 cookie 权限读入 API 身份验证 cookie,如果 cookie 丢失或过时,它会强制用户登录。如果 cookie 有效,它将作为身份验证令牌传递到每个 API 调用的参数或标头中。

关于飞行前选项请求的旁注:

您可能还必须处理将通过某些跨站点 AJAX 发送的 OPTIONS 飞行前请求(我认为这只是内容类型 JSON POSTS 的问题,但不要引用我),因为它们将在 Rails 中触发 ActionController::RoutingError (No route matches [OPTIONS]) 错误。推荐的答案是使用 rack-cors gem,这确实解决了问题。

见:

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。