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!
Top comments (0)