Sinatra - Response.Set_Cookie Doesn't Work

Sinatra - response.set_cookie doesn't work

The documentation on http://sinatra-book.gittr.com/#cookies says to use the set_cookie helper, but in newer versions of Sinatra (at least from 1.2.0+ and possibly earlier), you should use response.set_cookie to set cookies.

response.set_cookie("my_cookie", :value => "value_of_cookie",
:domain => myDomain,
:path => myPath,
:expires => Date.new(2020,1,1))
cookie = request.cookies["my_cookie"]

SUMMARY

don't set localhost as a domain for your cookies because you need to set it to "" or FALSE

How to set and read raw cookie in Ruby/Sinatra

Use Sinatra Cookies http://www.sinatrarb.com/contrib/cookies.html

require "sinatra/cookies"
cookies[:something] = 'foobar'

You can also read raw cookies in the request object:

request.cookies 

As described in Accessing the Request Object

There is also the set_cookie method of the response object

response.set_cookie("my_cookie", :value => "value_of_cookie",
:domain => myDomain,
:path => myPath,
:expires => Date.new(2020,1,1))
  • https://stackoverflow.com/a/5078196/156746
  • http://craig-russell.co.uk/2013/01/31/persistent-cookies-sinatra.html#.U9KVFIBdWUA

Why cookie doesn't work using Sinatra and Omniauth?

Is was a trivial problem, just add the path to the cookie: response.set_cookie 'test', {:value=> "facebook_callback", :path => "/"}

The reason why I did not notice was that there is a redirect to "/", so Chrome was only showing me the cookies for the path "/". Removing the redirect, I notice I have two cookies named "test". One with "/" path and the other with "/auth" path.

Sinatra unable to set cookies from helper file

When you require 'sinatra' certain magic things happen that brings a bunch of stuff into scope and essentially turns your app.rb into an instance of Sinatra::Application. The cookies method is only defined on instances like this – it isn’t present on other classes automatically.

What you probably want to do is turn your helper into a real Sinatra style helper by making it a module and then loading it using the helpers keyword, which will just make these instance methods:

module SessionsHelper

def sign_in(user)
cookies[:remember_token] = { value: user.remember_token, expires: 20.years.from_now.utc }
self.current_user = user
end

...
end

And in your main file:

require './helpers/sessions_helper'
helpers SessionsHelper

...

post '/sign_in' do
user = User.find_by(email: params[:email])
if user && user.authenticate(params[:password])
sign_in user
redirect '/'
else
...
end

You might like to read more about this in the README.

ActionDispatch::Cookies not setting Set-Cookie header in response but response.set_cookie does

I got the reason for this behavior. Actually other team deployed an application gateway on production. This result in the Rails server getting HTTP request which was HTTPS initially.

Now as I have marked my cookies to be secure: true, it looks like ActionDispatch::Cookies does not even send cookies in response to a request if the protocol is HTTP. It will only send if protocol is HTTPS. If I disable the secure by secure: false then it work or if I disable the application gateway then it work with ActionDispatch::Cookie.

It seems strange as secure is a client side attribute, but from behaviour of ActionDispatch::Cookies it looks like it don't even send cookies from server if protocol is HTTP and secure is set to true.

Although I didn't find any documentation of this behavior, but this is how it's working.

Sinatra cookies vanish on certain routes?

The problem is that the cookie is set with path /cookie. When you set a cookie your can specify a path, which is effectively a sub-part of the Website that you want the cookie to apply to. I guess Sinatra/Rack use the path of the current request by default which in /cookie/set would be /cookie.

You can make it work the way you expect by explicitly specifying the path:

  response.set_cookie("TestCookie", {
:expires => Time.now + 2400,
:value => "TestValue",
:path => '/'
})

Or you could set the cookie at a route called say /cookie-set rather than /cookie/set

Set cookie expiration time in Ruby

Sinatra doesn't have the ActiveSupport library which provides a helper for number-to-time, so 1.hour.from_now doesn't works here.

You should use this:

class SinatraApp < Sinatra::Base

use Rack::Session::Cookie, :key => 'rack.session',
:domain => 'foo.com',
:path => '/',
:expire_after => 2592000, # In seconds
:secret => 'some_secret'

And set a time in seconds. Because the Sinatra session comes from Rack::Session.

HOW TO ENABLE SESSIONS WITH SINATRA

How do I manually set cookie in rails app?

Finally I managed to solve it. So, I added rack_request.rb in initializers. And here's the code for it:

require 'rack'
require 'rack/request'
require 'rack/utils'

Rack::Request.class_eval do
def cookies
hash = @env["rack.request.cookie_hash"] ||= {}
string = @env["HTTP_COOKIE"] || "_session_id=#{@env['HTTP_X_SESSION_ID']}"

unless string =~ /\s*_session_id=/i
if @env['HTTP_X_SESSION_ID'].present?
string << "; _session_id=#{@env['HTTP_X_SESSION_ID']}"
end
end

# require 'colorize'
#
# Rails.logger.info 'from cookies'.green
# Rails.logger.info (string.blue)

return hash if string == @env["rack.request.cookie_string"]
hash.clear

# According to RFC 2109:
# If multiple cookies satisfy the criteria above, they are ordered in
# the Cookie header such that those with more specific Path attributes
# precede those with less specific. Ordering with respect to other
# attributes (e.g., Domain) is unspecified.
cookies = Rack::Utils.parse_query(string, ';,') { |s| Rack::Utils.unescape(s) rescue s }
cookies.each { |k, v| hash[k] = Array === v ? v.first : v }
@env["rack.request.cookie_string"] = string
hash

end
end

And I'm sending 'X-SESSION-ID' in my ajaxHeaders for session id.



Related Topics



Leave a reply



Submit