I've spend a good deal of time with Rails Basic Authentication scaffold. I think I installed it on a new app in late January and have spent way to much time trying to figure it out. While I've used Rails since v 0.9, I'm just a hobbyist and not very good or fast.

I did write a post a few weeks back on the same subject. Rails Basic Authorization (after Basic Authentication)

Rails Basic Authorization (after Basic Authentication) that was my first attempt at using it. I think the scaffold came out late last year. There is quit a bit written about it. I'll just add a little more to that.

One thing missing was Session Expiry - mentioned in several posts. Leaving a page open just didn't seem right.

I added it! But to took me a while before I figured out I was just going in circles. Spent a lot of time trying to figure out how to terminate a session. I didn't realize that it was simple as terminate_session. I though the methods in authentication.rb were private! There not!

I added 6 lines to authentication.rb. My demo app is a Blog type app that has a public view and a private view. Private being adding articals and a few other thing. Public - just to read the articles. I had a problem that if I was in the public view, I would just sign-in again (with a login_path I added). That would generate a new Session and would orphan the last one. To get rid of that I added 6 lines to authentication.rb:

def start_new_session_for(user)
  # klude to stop dual logins using login
  has_session = Session.find_by(user_id: user.id) # should be 0 or 1
  if has_session
    Current.session = has_session
    cookies.signed.permanent[:session_id] = { value: Current.session.id, httponly: true, same_site: :lax }
  else
    user.sessions.create!(user_agent: request.user_agent, ip_address: request.remote_ip).tap do |session|
      Current.session = session
      cookies.signed.permanent[:session_id] = { value: session.id, httponly: true, same_site: :lax }
    end
  end
end

For the missing piece - session_expiry - I added 12 lines to the application_controller.rb.

class ApplicationController < ActionController::Base
  include Authentication
  allow_browser versions: :modern
  before_action :session_expiry

    def session_expiry
    if Current.session
      key = "#{Current.session.id}_expires_at"
      if session[key].present? && session[key] < Time.now
        terminate_session
        reset_session
        redirect_to root_path #, flash: {alert: "Your session has expired!"}
      else
        session[key] = Time.now + 2.hours
      end
    end
  end

EDIT: Had to add the session.id to the :expires_at attribute. The original was global and not tied to the session.

I have some versions in other/older apps that session_expiry is twice a long and convoluted! This is kinda simple. Just set a session attribute!

That's it. Just a short piece on missing pieces!