bin/rails generate authentication: Rails 8's generator
A command that ships with this app's Rails
bin/rails generate authentication ships inside railties-8.1.3.1, the Rails version this app runs, and its USAGE file says what it does:
Description:
Generates a basic authentication system with users, sessions, and password reset.
Example:
`bin/rails generate authentication`
Run against a fresh Rails 8 app, it produces a working sign-in system: a User model, a Session model, a controller, a concern every other controller can include, password reset mailers, and the routes and migrations behind all of it. Every file this course describes comes from the generator's installed templates, quoted rather than paraphrased.
What create_authentication_files generates
The generator's source, authentication_generator.rb:
def create_authentication_files
template "app/models/session.rb"
template "app/models/user.rb"
template "app/models/current.rb"
template "app/controllers/sessions_controller.rb"
template "app/controllers/concerns/authentication.rb"
template "app/controllers/passwords_controller.rb"
template "app/channels/application_cable/connection.rb" if defined?(ActionCable::Engine)
if defined?(ActionMailer::Railtie)
template "app/mailers/passwords_mailer.rb"
template "app/views/passwords_mailer/reset.html.erb"
template "app/views/passwords_mailer/reset.text.erb"
end
end
Six files at minimum, more if the app loads Action Cable or Action Mailer (most Rails 8 apps load both by default, so in practice it's usually all of them). The next two lessons read the four that matter most for how sign-in works: the Authentication concern, Current, Session and SessionsController.
The routes and migrations it adds
Same generator, same file:
def configure_authentication_routes
route "resources :passwords, param: :token"
route "resource :session"
end
def add_migrations
generate "migration", "CreateUsers", "email_address:string!:uniq password_digest:string!", "--force"
generate "migration", "CreateSessions", "user:references ip_address:string user_agent:string", "--force"
end
Two migrations. users gets a required, unique email_address and a password_digest, the column has_secure_password writes BCrypt hashes into. sessions gets a user_id foreign key for belongs_to, plus ip_address and user_agent, so each login is a record you can inspect.
bcrypt, handled either way
def enable_bcrypt
if File.read(File.expand_path("Gemfile", destination_root)).include?('gem "bcrypt"')
uncomment_lines "Gemfile", /gem "bcrypt"/
bundle_command("install --quiet")
else
bundle_command("add bcrypt", {}, quiet: true)
end
end
A fresh rails new app ships with gem "bcrypt" commented out in its Gemfile; BCrypt is the password-hashing gem Rails recommends. The generator uncomments the line if it's there, or adds the gem if it isn't. Either way, has_secure_password, which every file in this course depends on, has BCrypt available.
What this course covers
Seven lessons, checked against this app's installed Rails and its hand-built code. Lesson 2 covers the generator's concern, Current and Session model. Lesson 3 covers SessionsController and two Rails 8 features quoted from their installed source, User.authenticate_by and the rate_limit controller DSL. Lesson 4 covers this app's own, different system: Identity::User, Identity::Current and Auth::SessionsController. Lesson 5 covers Auth::AuthenticateUserService and the security choices in it. Lesson 6 compares what each system has and lacks. Lesson 7 puts it together, with a small Ruby challenge modeled on this app's lockout logic.
This app didn't run this generator. The next lessons show what it built instead, and why that's a different engineering choice, not a worse one.
Keep going with lesson 2
The generated concern, Current, and a database-backed session
How the generated concern protects every action by default, and how Current and a Session row track logins.
A free account also gives you the quizzes, your progress and notes, and the discussion.