web-dev-qa-db-ja.com

「SameSite = None;」を追加するRails Rackミドルウェア経由?

2020年2月4日 、Google Chromeでは、すべてのクロスサイトCookieにSameSite=None;を追加する必要があります。 Rails 6.1以降Rails 6.0はRails Cookieハッシュにsame_site: :none オプションを追加しました:

cookies["foo"]= {
  value: "bar",
  expires: 1.year.from_now,
  same_site: :none
} 

ただし、古いRails 5.xアプリは、same_siteオプションハッシュにアクセスするためのアップグレードを受け取りません。私はSameSite=None; cookieオプションを手動でコントローラのRailsに手動で追加できることを知っています:

response.headers["Set-Cookie"] = "my=cookie; path=/; expires=#{1.year.from_now}; SameSite=None;"

しかし、私のRails 5.xアプリは、Cookieを変更する複雑なCookieオブジェクトを使用しています。それらを分解するのではなく、SameSite=None;属性で一度にすべてのCookieを手動で更新するようにRackミドルウェアを作成したいと思います。

このStackOverflowの回答 は、Rack Middleware内でCookieを更新するようにCookieを変更する方法を示しています。

# lib/same_site_cookie_middleware
class SameSiteCookieMiddleware
  def initialize(app)
    @app = app
  end

  def call(env)
    status, headers, body = @app.call(env)
    # confusingly, response takes its args in a different order
    # than rack requires them to be passed on
    # I know it's because most likely you'll modify the body, 
    # and the defaults are fine for the others. But, it still bothers me.

    response = Rack::Response.new body, status, headers

    response.set_cookie("foo", {:value => "bar", :path => "/", :expires => 1.year.from_now, same_site: :none})
    response.finish # finish writes out the response in the expected format.
  end
end
# application.rb
require 'same_site_cookie_middleware'
config.middleware.insert_after(ActionDispatch::Cookies, SameSiteCookieMiddleware)

このRackミドルウェアコードを書き換えて、既存のCookieにSameSite=None;を手動で追加するにはどうすればよいですか?

5
Kelsey Hannan

更新:Rails 5.x以下の場合、 _Rails_same_site_cookie_ gemが良いことがわかりました_SameSite=None;_をアプリのすべてのCookieに追加するためのオプション。ミドルウェアを使用してそれを行います。

0
Kelsey Hannan

Cookieを設定すると、expirydomainpathなどのCookieプロパティを変更できなくなります。

Cookieがすでに設定されている場合、ブラウザはCookieの名前と値のみを返します。Cookieプロパティを上書きすると、新しいCookieが作成されます。既存のCookieを削除し、同じ名前と値で新しいCookieを作成することをお勧めします。

headers['Set-Cookie']は、ブラウザに新しいCookieを作成するように指示し、ミドルウェアで値を変更しても、属性値をほとんど制御できません。

私は答えました hereRack::Utils.set_cookie_header!メソッドを変更することでこれをどのように実現できるか。

0
anil.n

Rails 5ヘッダーがフリーズする問題がありました。これはCarsonの回答に似ていますが、この問題を回避します。Rails 5 <とRails 5+。

# frozen_string_literals: true

class SameSiteCookies

  def initialize(app)
    @app = app
  end

  def call(env)
    status, headers, body = @app.call(env)

    set_cookie_header = headers['Set-Cookie']

    if set_cookie_header && !(set_cookie_header =~ /SameSite\=/)
      # the set cookie header variable is frozen
      new_set_cookie_header = set_cookie_header.dup
      new_set_cookie_header << ';' if !(set_cookie_header =~ /;$/)
      new_set_cookie_header << ' SameSite=None'
      new_set_cookie_header << '; Secure' if is_ssl?

      headers['Set-Cookie'] = new_set_cookie_header

    end

    [status, headers, body]
  end

  private

  def is_ssl?
    # custom logic for my application
  end
end

ミドルウェアを挿入する

Rails.application.config.middleware.insert_before(ActionDispatch::Cookies, SameSiteCookies)
0
cesartalves