DEV Community

Steve Alex
Steve Alex

Posted on • Edited on

Rails 8 Basic Auth - Missing Pieces

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
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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!

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

👋 Kindness is contagious

Explore a trove of insights in this engaging article, celebrated within our welcoming DEV Community. Developers from every background are invited to join and enhance our shared wisdom.

A genuine "thank you" can truly uplift someone’s day. Feel free to express your gratitude in the comments below!

On DEV, our collective exchange of knowledge lightens the road ahead and strengthens our community bonds. Found something valuable here? A small thank you to the author can make a big difference.

Okay