I have a controller that attempts takes form inputs, set values in a cookie and then redirect to a page that will pull from that cookie.
The problem is that the cookie is never set in the redirect headers.
Notes: I've tested in Chrome and FF. Rails version is 4.0.13. Setting cookies w/o a redirect works as expected.
Here's the controller code:
def create
request.cookies[:foo] = "bar"
# also tried:
# cookies[:foo]="bar"
# cookies.signed[:foo]="bar"
# cookies[:foo] = {
# value: "bar",
# expires: 1.month.from_now,
# domain: ".myapplicationhostname.com"
# }
redirect_to root_url
end
The response header on the redirect doesn't contain a Set-Cookie attribute and as such, the cookie values aren't available in the controller/action in the redirected-to path.
I've found some contradictory evidence that some browsers don't accept cookies in redirects, but it appears that that's not the case anymore? And anyways, neither FF or Chrome are showing a Set-Cookie
in the response header, so it doesn't appear this is a browser issue.
Here's the header response from cURL, note the lack of Set-Cookie
:
HTTP/1.1 302 Moved Temporarily
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-UA-Compatible: chrome=1
Location: http://app.mydomain.com:3000/
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache
X-Request-Id: 1fc1c7e5-7489-4720-bb70-28588f3abcb6
X-Runtime: 4.688166
Connection: close
Server: thin 1.6.2 codename Doc Brown
How do I get rails to set cookies (or at least set the header) on redirects?
It appears that the cause of this is actually CSRF protection kicking in. The controller had instantiated a NullCookieJar
which prevents the writing of cookies when there's a potentially forged POST.
This is because my controller was being set up to respond to an off-site form, thus no access to the CSRF token.
So, if you're running into this when submitting an off-site form to your Rails app, you'll need to disable the CSRF check or write your own verification method as described in the answer to the SO question: "Receive POST from External Form".
Summarized here:
Disabling Check
skip_before_filter :verify_authenticity_token, only: :my_action
Custom Check
skip_before_filter :verify_authenticity_token, :only => :my_action
before_filter :verify_custom_authenticity_token, :only => :my_action
def verify_custom_authenticity_token
# checks whether the request comes from a trusted source
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With