wuliwong
wuliwong

Reputation: 4368

How to properly start a session using cookies, store it and access it in a Sinatra app using Rack sessions

I have a Sinatra app running on Heroku. I've had a really tough time properly setting up the cookies for my users. I've been looking at examples and documentation for a couple days now and just can't seem to crack the problem. I would like to have my users login with a email and password. If the login is successful, I want to create a cookie which expires after some set amount of time. I want the user to remain logged in if they close and re-open their browser or if I push new code to Heroku. I think that is just normal use of cookies, so if someone can help me get it going, I'd be very grateful.

Here is how I think I'm supposed to setup the post '/login' route.

post '/login/?' do

  #do_login is a helper method which checks if the user's credentials are correct

  if do_login
    use Rack::Session::Cookie, :key => 'rack.session',
                               :domain => 'www.Feistie.com',
                               :path => '/',
                               :expire_after => 2592000,
                               :secret => 'a_30_character_key',
                               :user_id => params[:user_id]
  end

end

Even if that is correct, I don't really understand it. What is the :key? I'm assuming :domain should just be set to my website as I did. What about :path? Why is :path set to '/'? Is there a place I actually set the secret key for my Rack app? I'm not totally clear on how cookie security works. I'm also not sure if I can add :user_id to the hash the way I did.

Then next part is setting up a helper "logged_in?" to see if someone is logged in?

def logged_in?
  !session.nil?
end

That is probably wrong, but I figured I'd try.

I also need to be able to check who the current user actually is. I used to do this by session[:user_id] == @user.id or something similar. The main question I have is how do I access the :user_id value in the cookie?

Finally the logout.

post '/logout/?' do
  session.clear
end

If you guys could get me on track with all this, it would be amazing! Thanks in advance and if you need more info, I will be glad to provide.

Upvotes: 2

Views: 2974

Answers (2)

jchook
jchook

Reputation: 7220

It's much simpler than that. http://www.sinatrarb.com/faq.html#sessions

enable :sessions

post '/login/?' do
  if do_login
    session[:user_id] = params[:user_id]
  end
end

post '/logout/?' do
  session[:user_id] = nil
end

I generally try to keep session management to the business logic in get, post, before, etc blocks. You can use a before filter to "log-in" the current session's user.

before '*' do
  set :user_id, session[:user_id]
end

This is completely optional, but you can put any cookie config in your rackup file:

use Rack::Session::Cookie, 
    :key => 'rack.session',
    :path => '/',
    :expire_after => 14400, # In seconds
    :secret => 'change_me'

Upvotes: 3

fatnic
fatnic

Reputation: 509

You could just try setting it with response

response.set_cookie "user_id", {:value => params['user_id'], 
                                :expires => (Time.now + 52*7*24*60*60)}

And you can read it back any time before it expires with

request.cookies["user_id"]

To delete the cookie

response.delete_cookie "user_id"

...

Upvotes: 1

Related Questions