Accountless Auth with Rails
I wanted to give her an "admin" portal, but I really didn't want to add the typical account signup flow. It's only her logging in after all. I don't know about you, but I hate that every site I visit wants me to "sign up".
Rather than bringing in a huge gem like Devise or building some other complex "account management" system, here's how we did it.
Create a Basic Login Page and Authenticate Handler
I added a
login route with a form that accepts only a password. It posts back to an
authenticate route which is just hanging off the "welcome" controller. It permits a single parameter,
:password, and compares it against an application configuration value.
I added the following line to
config.admin_password = ENV["ADMIN_PASSWORD"] || "password"
Of course it defaults to "password" if nothing is set. I should probably change that to fail if the configuration is missing.
If it matches, I simply create a session with a fixed user id and redirect to the "admin" page.
Protect the Admin Pages
To project the pages I want to be authenticated, first I added a two methods to
class ApplicationController < ActionController::Base def authorize redirect_to login_path unless logged_in? end def logged_in? @current_user ||= session[:user_id] if session[:user_id] end helper_method :logged_in? end
Adapting the UI
Then in the controllers that need protecting I added "before actions":
class DrawingsController < ApplicationController before_action :authorize, only: [:edit, :update, :destroy] ...
The help method lets me hide or show UI based on the login state. For example, in
<% if logged_in? %> <a class="navbar-item" href="/drawings">Drawings</a> ... <% end %>
Make Sure You're on SSL
It may seem obvious, but only do this if your pages are secure. Once the cookie is set, anyone can just skim it if you're on an unsecured network. In
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. config.force_ssl = true
This works and works well. Safari will even offer to remember the password. It's a braindead simple way of getting the benefit of a typical heavy-handed account management with only a couple lines of code.