0

I want to make it so that a session has to be present in order to use a site. If not, then redirect to the root path, so that a user can choose whether to browse the site as a guest, log in or register. I'm using a basic authentication made from scratch, based on a Railscast.

in the app controller

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  before_action :set_artists
  before_filter :check_session
  helper_method :current_user

  private
        def set_artists
            @artists = Artist.all
        end

    def current_user
      @current_user ||= User.find(session[:user_id]) if session[:user_id]
    end

    def check_session
      unless current_user
        redirect_to root
      end
    end
end

I had a guest user logged in, then wiped out all of the guest users through the Rails console: User.where(guest: true).destroy_all. I have a rake task that wipes out guest sessions that are 1 day old, so this would a pretty typical situation. Trying to reload after that, the error comes up: Couldn't find User with 'id'=8

sivanes
  • 713
  • 1
  • 13
  • 22
  • You need to invalidate or remove your cookie from the browser. You can invalidate all existing cookies by changing [the secret key base](http://stackoverflow.com/questions/25426940/what-is-the-use-of-secret-key-base-in-rails-4). – max Jan 10 '17 at 22:02
  • 4
    You also may want to read up on [how sessions work in Rails](http://guides.rubyonrails.org/security.html#what-are-sessions-questionmark) since the whole concept of "requiring a session" is wrong. Every visitor to your rails application is given a session - but only those who allow cookies can "reclaim" a session after the initial visit. What you may mean is making Authentication manditory. (A guest user is also a form of authentication). – max Jan 10 '17 at 22:06
  • any suggestions on a good way to make sure that as a guest authentication gets wiped out when time comes, the user does not experience a crash like this because of cookies on their end? – sivanes Jan 11 '17 at 04:23

1 Answers1

2

The problem is that your users will keep their cookies, so when you run:

def current_user
  @current_user ||= User.find(session[:user_id]) if session[:user_id]
end

the user still has the session cookie with a :user_id and the call to User.find is failing to find the now-deleted user.

A solution is to replace this with a call that can fail, such as:

def current_user
  @current_user ||= User.find_by(id: session[:user_id]) if session[:user_id]
end

Where find will raise an exception if the User cannot be found, find_by will just return nil leaving your current_user empty.

That being said, I agree with the earlier commenter that this is not really the "Rails way." Deleting all the guest users each day is probably not the best way to get the behavior you want.

Instead, one idea is that you could add a timestamp to the User model indicating when the user was last asked to validate as a guest, and then if more than 24 hours have elapsed, you could bounce guest users back to the page that prompts them to register. You don't have to delete their User entry; you can just reuse it when they re-register.

arrbee
  • 241
  • 1
  • 2
  • Thank you for your response! What eventually happened was that Chrome started giving me the "too many reloads, clear your cookies" message (I'm paraphrasing), which didn't go away after clearing the cookies. Your correction to `current_user` didn't seem to fix it. I just commented out session_check stuff and logged back on as another guest user to get access to the app back. So, I'm doing something very wrong here. Seems that `find_by` returning `nil` causes a problem as well, as to even get back to the screen where a user can choose to be a guest still requires `current_user` to be something. – sivanes Jan 11 '17 at 17:49
  • This is supposed to be for a demo project that I will use in my application for an internship. This doesn't seem to be that crucial of a feature, and it will take some time to first and foremost comprehend it better conceptually. So, I'm thinking of just letting this one go for now. – sivanes Jan 11 '17 at 17:51