We will use Rails to initialize the project demo-rails-7-with-devise-series:
# Create a new rails project
$ rails new demo-rails-with-react-frontend
$ cd demo-rails-with-react-frontend
# Add required gem
$ bundler add devise
# Scaffold the app
$ bin/rails generate devise:install
$ bin/rails generate devise User
# Generate a home controller for us to test against
$ bin/rails generate controller home index
Updating our developer environment settings
Next, we need to update the default action mailer config at config/environments/development.rb:
We are going to update the application controller at app/controllers/application_controller.rb to always require a user to be logged in for all actions:
class ApplicationController < ActionController::Base
before_action :authenticate_user!
end
That last part is up to you. If you want to restrict the controllers that will be requiring auth, you can always add before_action :authenticate_user! to that file.
Setup routing
At this stage, we want to update our routes to set our Home controller index to the root route:
Rails.application.routes.draw do
devise_for :users
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
# Defines the root path route ("/")
root 'home#index'
end
Setup the Devise initializer
In my current version of Rails 7, I also needed to update the config/initializers/devise.rb file to uncomment the config.navigational_formats and add the :turbo_stream for the default Devise handler after signing up:
Let's set the values of app/views/home/index.html.erb to the following:
<h1>Home#index</h1>
<p>Find me in app/views/home/index.html.erb</p>
<%= link_to "Log out", destroy_user_session_path, data: { "turbo-method":
:delete } %>
We are only adding in that last line here.
Starting the server
Finally, we can migrate and start the server:
# Create and migrate the db
$ bin/rails db:create db:migrate
# Start the server (including the React app)
$ bin/rails s
At this stage, going to localhost:3000 will redirect us to our sign in route http://localhost:3000/users/sign_in.
Redirected to sign in
Select Sign up to redirect to our sign up route http://localhost:3000/users/sign_up.
Sign up
Signing up and viewing our page
Sign up with whatever credentials you wish.
I am going to use hello@example.com as the email and password as the password.
After signing up, you will be redirected to the root path and authenticated for the application. Hooray!
Authenticated
Things to note from the magic happening
A lot of magic happened when we ran the generate and install commands for Devise.
If you check under db/migrate/<timestamp>_devise_create_users.rb for the Devise migration, you will see that Devise setup a migration for us with some sensible defaults and commented out extras:
# frozen_string_literal: true
class DeviseCreateUsers < ActiveRecord::Migration[7.0]
def change
create_table :users do |t|
## Database authenticatable
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
# t.integer :sign_in_count, default: 0, null: false
# t.datetime :current_sign_in_at
# t.datetime :last_sign_in_at
# t.string :current_sign_in_ip
# t.string :last_sign_in_ip
## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
t.timestamps null: false
end
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
# add_index :users, :confirmation_token, unique: true
# add_index :users, :unlock_token, unique: true
end
end
You will also note that we also had some options to uncomment some strings to help us set up the Trackable, Confirmable and Lockable options. You can read up more on those options here.
We won't follow up too much on this here, but some of those options could have been added under the app/models/user.rb file. We will touch back on OmniAuth later in part five.
Also, when you do not generate the views, Devise handles the default views that we saw for both sign up and sign in. We will be generating and altering those views in part three.
Summary
Today's post kicked off the Devise series with a basic overview of getting Devise up and running with Rails 7.
In the next part, we will tackle using Redis for our session store instead of the default cookie store.