7

In my rails 3 app I use Omniauth for the user authentication part (fb/twitter).

Actually I follow this:

https://github.com/RailsApps/rails3-mongoid-omniauth

https://github.com/RailsApps/rails3-mongoid-omniauth/wiki/Tutorial

But, when I close the browser session expires and I need to login again. How can I keep the session for returning users?

Any help would be greatly appreciated!

Lamp
  • 1,084
  • 1
  • 14
  • 27
  • unclear: does this happen in your local environment/browser only? How does your test environment deal with HTTP cookies? – mkro Feb 09 '12 at 00:50
  • after login the session_controller stores user_id: session[:user_id] = user.id https://github.com/RailsApps/rails3-mongoid-omniauth/blob/master/app/controllers/sessions_controller.rb – Lamp Feb 09 '12 at 03:36
  • Can't really tell what happens in your application, but maybe you want to look into the cookie lifetime and other settings around rails seession cookies: http://oldwiki.rubyonrails.org/rails/pages/HowtoChangeSessionOptions – mkro Feb 14 '12 at 01:18

4 Answers4

9

What you want is not difficult, you only have to set a permanent cookie when the session is created and then retrieve this value when you set the current user.

In your ApplicationController, just change your current_user method to:

def current_user
  return unless cookies.signed[:permanent_user_id] || session[:user_id]
  begin
    @current_user ||= User.find(cookies.signed[:permanent_user_id] || session[:user_id])
  rescue Mongoid::Errors::DocumentNotFound
    nil
  end
end

And in your SessionsController, modify your create to set the cookie if user wants to:

def create
  auth = request.env["omniauth.auth"]
  user = User.where(:provider => auth['provider'], 
                    :uid => auth['uid']).first || User.create_with_omniauth(auth)
  session[:user_id] = user.id
  cookies.permanent.signed[:permanent_user_id] = user.id if user.really_wants_to_be_permanently_remembered
  redirect_to root_url, :notice => "Signed in!"
end
David
  • 4,080
  • 1
  • 26
  • 34
  • Thanks for your answer! I combined devise and my problem solved! – Lamp Feb 22 '12 at 17:37
  • You really should not be using the user_id in the signed cookie, the proper way would be to create a remember_me token in your user model, save that in the permanent cookie and when you don't have a current session, you create a new one by looking up the remember_me token. The tokens are harder to guess than changing your uid if a hacker figures out how to get around the cookie signing (its been done before). – Astra May 31 '12 at 19:24
4

Devise offers this functionality through its Rememberable module. OmniAuth integrates easily with it through the (you'd never guess it) OmniAuth module. It's even mentioned in the second link you posted!

andrew.rockwell
  • 621
  • 7
  • 18
1

Please make sure the cookie policy that your rails app follows does have sensible settings for your use case (see the link in my comment above). All I can imagine right now (knowing what I know, sitting where I sit) is that the cookie(s) ha(s/ve) properties that are suboptimal/undesirable in your context.

Please check the cookie settings in a browser debug/development tool such as firebug, firecookie or the chrome development tools.

Sorry, that's all I can come up with given my knowledge of the problem. Feel free to contact me again with more details on your cookie- and testing-setup.

My 2Cents.

mkro
  • 1,902
  • 14
  • 15
  • Thanks for your answer! But as you can see here it's not a cookie problem: http://stackoverflow.com/questions/4475726/devise-and-omniauth-remembering-oauth – Lamp Feb 15 '12 at 22:59
0

Here is how it works for me:

def google_oauth2
  @user = User.from_google(google_params)

  if @user.persisted?
    @user.remember_me = true
    sign_in @user
    ........
  end
end

There is another way to do it

Sasha Stadnik
  • 502
  • 1
  • 6
  • 16