Ryzal Yusoff
Ryzal Yusoff

Reputation: 1047

Devise not binding session (Omniauth) in Rails 4

I use Omniauth with Devise in my rails app. I managed to get the user signed in correctly when they are using omniauth (in this case, facebook). When the user try to login by using their email and password instead of omniauth, the app will still logged the user in but it does not store the session. So, there is no sign out button being shown and the user cannot do the thing that he/she suppose to do.

This is my route for user :

  devise_for :users, path_names: {sign_in: "login", sign_out: "logout"}, controllers: {registrations: 'registrations', omniauth_callbacks: "omniauth_callbacks"}, :skip => [:sessions]
  as :user do
    get 'sign-in' => 'devise/sessions#new', :as => :new_user_session
    post 'sign-in' => 'devise/sessions#create', :as => :user_session

    get '/users/sign_out' => 'devise/sessions#destroy'

    resources :users_admin, :controller => 'users'

  end

This is my OmniauthCallbacksController:

class OmniauthCallbacksController < Devise::OmniauthCallbacksController
    def all
        user = User.from_omniauth(request.env["omniauth.auth"])
        if user.persisted?
            session[:user_id] = user.id
            sign_in_and_redirect user, notice: "Signed in!"
        else
            session["devise.user_attributes"] = user.attributes
            redirect_to new_user_registration_url
        end 
    end
    alias_method :facebook, :all    
end

This is my SessionController:

class SessionsController < ApplicationController

    def create
        user = User.from_omniauth(env["omniauth.auth"])
        session[:user_id] = user.id
        redirect_to root_url
    end 

    def destroy
        session[:user_id] = nil
        redirect_to root_url
    end

end 

And the tutorial that I am following is here: https://www.youtube.com/watch?v=X6tKAUOMzCs

Please help..thanks!

Upvotes: 0

Views: 951

Answers (2)

monteirobrena
monteirobrena

Reputation: 2620

For me, only add sign_in user after persiste solves. The sign_in user will add the user into the current_user and set the session.

class OmniauthCallbacksController < Devise::OmniauthCallbacksController
    def all
        user = User.from_omniauth(request.env["omniauth.auth"])

        if user.persisted?
            sign_in user
        else
            session["devise.user_attributes"] = user.attributes
            redirect_to new_user_registration_url
        end 
    end
end

end

Upvotes: 0

Jeiwan
Jeiwan

Reputation: 954

The code of SessionsController is wrong. In create action you're trying to authenticate user from omniauth, but this controller is not used for OAuth authentication. This is why it doesn't save anything in session. Moreover, there's seem to be a typo: you use env["omniauth.auth"] instead of request.env["omniauth.auth"].

Actually, you don't need to modify SessionsController or create your own. Devise's default SessionsController works fine. You just need to turn on Omniauthable, connect omniauth-provider and that's all. Route settings would look like this:

devise_for :users, controllers: {omniauth_callbacks: 'omniauth_callbacks'}

You can find the code from the video in this repo: https://github.com/railscasts/235-devise-and-omniauth-revised/tree/master/blog-after Hopefully, it will help you.

Upvotes: 0

Related Questions