Sinatra - response.set_cookie doesn't work - ruby

I need to use a cookie for my Sinatra application. If I use the simpliest method is works:
response.set_cookie('my_cookie', 'value_of_cookie')
but I need some options such as domain and expire date so I try this:
response.set_cookie("my_cookie", {:value => 'value_of_cookie', :domain => myDomain, :path => myPath, :expires => Date.new})
does not work. No cookie is made. I need this so much....
Please help... thanks!

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

Related

Get Postgres-activerecord setup to work both locally and in Heroku

I'm automating DB creation (with a Rakefile in a Sinatra App).
I would like to be able to run the rakefile from my Linux user "pete" (eg pete#pete_laptop: /path $ rake db:create) AND from Heroku.
It comes down to the settings in my config/database.rb:
ActiveRecord::Base.establish_connection(
:adapter => db.scheme == 'postgres' ? 'postgresql' : db.scheme,
:host => db.host,
:port => db.port,
# pete#ubuntu_14.04_laptop--------
# :username => 'pete',
# :password => 'password',
# OR
# heroku -----------------
# :username => db.user,
# :password => db.password,
:database => DB_NAME,
:encoding => 'utf8'
)
If I use the pete#ubuntu_laptop settings, the database works in localhost but not in Heroku,
If I use the heroku settings, the database works in localhost but not in Heroku.
How can I setup this file/my ubuntu laptop so that the app works both on localhost & in Heroku?
Cheers,
Pete
You can use environment variables which can be accessed like ENV["PG_USER"] in Ruby. If you want to use it in a yml file you can put it in erb tags <%= ENV["PG_USER"] %> and render it with erb before passing it to your config.
You can set environment variables in your .bashrc or you can use something like the dotenv gem. On heroku you can set environment variables like heroku config:set PG_USER=postgres.
But check whether this is really necessary for heroku. In Rails, for instance, heroku provides a database configuration, so there is no need to configure it.
oK! With help got it working!
used:
ActiveRecord::Base.establish_connection(
:adapter => db.scheme == 'postgres' ? 'postgresql' : db.scheme,
:host => db.host,
:port => db.port,
:username => ENV['PG_USER'] || db.user,
:password => ENV['PG_PASSWORD'] || db.password,
:database => DB_NAME,
:encoding => 'utf8'
)
AND
added this to my shell-rc (in my case ~/.zshrc)
export PG_USER='pete'
export PG_PASSWORD='password'
now in my local environment the username & password pick up the ENV['PG...] variables from the terminal I launch the app in.
Note: 'export' is important - without it the variables don't get sent to the app's 'ENV'

How do I limit access to API endpoints in Rails 4?

I'm trying to figure out how to limit Cross-Domain access to a JSON API for 3 sites. It seems you have a few different things to deal with in Rails 4, such as:
protect_from_forgery with: :exception which prevents CSRF attacks.
Changing this to protect_from_forgery with: :null_session seems to allow the world to access it.
Trying this in application.rb:
config.action_dispatch.default_headers.merge!({
'Access-Control-Allow-Origin' => '*',
'Access-Control-Request-Method' => 'GET, POST, PUT'
})
This, again, allows the world to access your endpoints, however, it only allows a max of one site if you replace '*' with a URL. I'd like at least 3.
There are also gems you could use such as rack-cors:
In application.rb:
config.middleware.insert_before 0, "Rack::Cors" do
allow do
origins 'http://myFirstSite.com', 'http://mySecondSite.com', 'http://myThirdSite.com'
resource '/article_pages',
:headers => :any,
:methods => [:post],
:max_age => 0
resource '/article_pages',
:headers => :any,
:methods => [:put],
:max_age => 0
resource '*',
:headers => :any,
:methods => [:get],
:max_age => 0
end
end
This latest example is supposed to only allow the sites specified in origins, but seems to allow any site (as I've tested). I'm not sure if this is a configuration issue but it seems to be configured correctly via their docs.
There are also examples as such: https://gist.github.com/dhoelzgen/cd7126b8652229d32eb4
This one appears to allow ANY site to access the one endpoint inside the controller for which headers['Access-Control-Allow-Origin'] = '*' is set in a filter. Again, I'd like to limit the access to 3 sites.
What is a standard way of allowing only a few sites to access one public endpoint while blocking all other sites?

How do I read cookies with Sinatra?

I've been having a lot of trouble getting cookies working with my web application running Sinatra.
I am currently setting the cookies with:
response.set_cookie(:id, :value => id, :domain => "XX.XXX.XXX.XXX", :expires => Time.now + 86400000)
where the domain is the IP address of the web app (no proper domain for now). This correctly sets the cookie because I can find the cookie in my web browser's cookies and the values are correct.
However, I can't read the cookie. If I write:
id = request.cookies[:id]
then id just becomes a null value.
Is there something I'm missing (for instance are there any settings I should be aware of)? How can I get this to work?
All help would be appreciated. Thanks in advance.
OK, I managed to figure it out. I wasn't setting the path so it wouldn't work across different URLs.
I found this fixed my problem:
response.set_cookie(:id, :value => id, :domain => "XX.XXX.XXX.XXX", :path => "/", :expires => Time.now + 86400000)

Is there any way to get resque-web to work with Redis To Go hosted redis instance?

Is there any way to get resque-web to work with a Redis To Go hosted redis instance?
UPDATE:
#Nemo157's suggestion was correct. Ended up creating a test-evn.rb containing:
uri = URI.parse(" redis://XXXX#catfish.redistogo.com:9122")
Resque.redis = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
Pass it the config file you're using to setup redis in the app, e.g.
resque-web ./environment.rb
where environment.rb contains something like:
Resque.redis = Redis.new(:host => "path.to.host", :port => 6379)
Note: I haven't tested this since all my redis instances have been on localhost, but that's my understanding of how it works.

setting cookies

Okay, so I'm trying to set cookies using Ruby. I'm in a Rack environment. response[name]=value will add an HTTP header into the HTTP headers hash rack has. I know that it works.
But the following method of setting cookies doesn't work:
def set_cookie(opts={})
args = {
:name => nil,
:value => nil,
:expires => Time.now+314,
:path => '/',
:domain => Cambium.uri #contains the IP address of the dev server this is running on
}.merge(opts)
raise ArgumentError, ":name and :value are mandatory" if args[:name].nil? or args[:value].nil?
response['Set-Cookie']="#{args[:name]}=#{args[:value]}; expires=#{args[:expires].clone.gmtime.strftime("%a, %d-%b-%Y %H:%M:%S GMT")}; path=#{args[:path]}; domain=#{args[:domain]}"
end
Why not? And how can I solve it? Thanks.
It turns out that you can't use an IP address with cookies, at least not with also specifying a port.

Resources