问题
A cookie associated with a cross-site resource at https://example.com/ was set without the SameSite
attribute. It has been blocked, as Chrome now only delivers cookies with cross-site requests if they are set with SameSite=None
and Secure
. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032.
Please let me know how to set the SameSite cookie attribute. Thanks in advance.
回答1:
The way to set custom headers is to add the line below to your controller action:
response.headers['Set-Cookie'] = 'Secure;SameSite=None'
.
回答2:
Action dispatch cookies is responsible for writing cookies to browser set in application, this uses Rack::Utils.set_cookie_header!
.
Support for SameSite
has been added after rack version 1.6, you need to check your rack version in Gemfile and if it is < 1.6 you need to add the following code in config/initializers
require 'rack/utils'
module Rack
module Utils
def self.set_cookie_header!(header, key, value)
case value
when Hash
domain = "; domain=" + value[:domain] if value[:domain]
path = "; path=" + value[:path] if value[:path]
max_age = "; max-age=" + value[:max_age] if value[:max_age]
expires = "; expires=" +
rfc2822(value[:expires].clone.gmtime) if value[:expires]
secure = "; secure" if value[:secure]
httponly = "; HttpOnly" if value[:httponly]
same_site =
case value[:same_site]
when false, nil
nil
when :none, 'None', :None
'; SameSite=None'
when :lax, 'Lax', :Lax
'; SameSite=Lax'
when true, :strict, 'Strict', :Strict
'; SameSite=Strict'
else
raise ArgumentError, "Invalid SameSite value: #{value[:same_site].inspect}"
end
value = value[:value]
end
value = [value] unless Array === value
cookie = escape(key) + "=" +
value.map { |v| escape v }.join("&") +
"#{domain}#{path}#{max_age}#{expires}#{secure}#{httponly}#{same_site}"
case header["Set-Cookie"]
when nil, ''
header["Set-Cookie"] = cookie
when String
header["Set-Cookie"] = [header["Set-Cookie"], cookie].join("\n")
when Array
header["Set-Cookie"] = (header["Set-Cookie"] + [cookie]).join("\n")
end
nil
end
end
end
Once done you can set SameSite
attribute while creating a new cookie, for ex:
cookies['testing'] = {
value: 'test',
path: '/',
expiry: 1.weeks.from_now,
same_site: :none
}
you can also add the same_site: <value>
to your session store as well.
Hope this helps!
回答3:
In Rails 6.0 and 6.1 the same_site attribute has been added:
cookies["foo"] = {
value: "bar",
secure: Rails.application.config.secure_cookies,
same_site: "None"
}
For Rails 5.x and lower, the rails_same_site_cookie gem is a good option for adding SameSite=None;
to all your app's cookies. It uses middleware to do it.
回答4:
A backport of fixes to rack was contributed here.
https://github.com/rack/rack/pull/1547
It won't be released, so you'll likely need to use a fork of rack in your Gemfile
.
https://bundler.io/v1.17/guides/git.html
回答5:
What I did is the following:
In session_store.rb
I configured:
MyApp::Application.config.session_store :cache_store, key: COOKIE_NAME, :expire_after => 1.days, :expires_in => 1.days, :domain => 'mydomain.com', same_site: :none
And I added this monkey patch:
require 'rack/utils'
module Rack
module Utils
def self.set_cookie_header!(header, key, value)
case value
when Hash
domain = "; domain=" + value[:domain] if value[:domain]
path = "; path=" + value[:path] if value[:path]
max_age = "; max-age=" + value[:max_age] if value[:max_age]
expires = "; expires=" +
rfc2822(value[:expires].clone.gmtime) if value[:expires]
# Make it always secure, even in HTTP
# secure = "; secure" if value[:secure]
secure = "; secure"
httponly = "; HttpOnly" if value[:httponly]
same_site =
case value[:same_site]
when false, nil
nil
when :none, 'None', :None
'; SameSite=None'
when :lax, 'Lax', :Lax
'; SameSite=Lax'
when true, :strict, 'Strict', :Strict
'; SameSite=Strict'
else
raise ArgumentError, "Invalid SameSite value: #{value[:same_site].inspect}"
end
value = value[:value]
end
value = [value] unless Array === value
cookie = escape(key) + "=" +
value.map { |v| escape v }.join("&") +
"#{domain}#{path}#{max_age}#{expires}#{secure}#{httponly}#{same_site}"
case header["Set-Cookie"]
when nil, ''
header["Set-Cookie"] = cookie
when String
header["Set-Cookie"] = [header["Set-Cookie"], cookie].join("\n")
when Array
header["Set-Cookie"] = (header["Set-Cookie"] + [cookie]).join("\n")
end
nil
end
end
end
来源:https://stackoverflow.com/questions/59195284/how-to-set-samesite-attribute-to-none-secure-in-rails3-1-12-and-ruby1-9-3