I have created a Ruby on rails application where you can create a account. When you then log your self in, a session is created. In the ApplicationController.rb there is a before_action where it is checked if a user is logged in, except for the views register and welcome. And I have a @current_user variable which is true when there is a user logged in. The login works fine. When you press the login button a session is created but as soon as I reload the page or click on a link to an other page, the @current_user equals null. The session still exists, but the @current_user is false.
How can I get a session to last until the user clicks on a logout button? Or how can i fix my @current_user variable?
Thanks for your help!
application_controller.rb
class ApplicationController < ActionController::Base
skip_before_action :verify_authenticity_token
before_action :require_login, except: [:welcome, :register, :create]
private
def require_login
unless @current_user
#reset_session
flash[:error] = "You must be logged in"
render json: {status: "You are not logged in", user: @current_user, session: session}
#render sessionhandling_welcome_path
end
end
end
current_user_concern.rb
module CurrentUserConcern
extend ActiveSupport::Concern
included do
before_action :set_current_user
end
def set_current_user
if session[:user_id]
@current_user = User.find(session[:user_id])
end
end
end
sessions_controller.rb
class SessionsController < ApplicationController
include CurrentUserConcern
def create
user = User.find_by(email: params["user"]["email"]).try(:authenticate, params["user"]["password"])
if user
session[:user_id] = user.id
session[:expires_at] = Time.current + 1.minutes
#render "sessionhandling/home"
render json: {status: :created, logged_in: true, user: user, expires_at: session}
else
render json: {status: 401}
end
end
def logged_in
if @current_user
render json: {logged_in: true, user: @current_user}
else
render json: {logged_in: false}
end
end
def logout
reset_session
render json: {status: 200, logged_out: true}
end
end
home.html.erb
<h1>Home</h1>
<%= link_to "Controllpanel", sessionhandling_controllpanel_path %>
<%= link_to "Logout", logout_path %>
You are missing this part:
application_controller.rb
class ApplicationController < ActionController::Base
include CurrentUserConcern # This is missing
skip_before_action :verify_authenticity_token
before_action :require_login, except: [:welcome, :register, :create]
private
def require_login
unless @current_user
#reset_session
flash[:error] = "You must be logged in"
render json: {status: "You are not logged in", user: @current_user, session: session}
#render sessionhandling_welcome_path
end
end
end
Also, I would change the CurrentUserConcern
to handle the #require_login
as well. There is no guarantee of which before_action
will run first, require_login
or set_current_user
and even if it is guaranteed then it's confusing.