40
loading...
This website collects cookies to deliver better user experience
rails new authentication
cd authentication
WelcomeController
. rails g controller welcome index
config/routes.rb
like so:Rails.application.routes.draw do
get 'welcome', to: 'welcome#index'
root to: 'welcome#index'
end
welcome_controller.rb
file in app/controllers
class WelcomeController < ApplicationController
def index
end
end
index.html.erb
file in app/views/welcome
. By default, rails render a view that corresponds with the name of the controller. Now, add some content for that page in the file:<h1>Welcome Page</h1>
gem 'bcrypt', '~> 3.1.7'
in Gemfile
and run bundle install
to install the gem.gem 'bcrypt', '~> 3.1.7'
bundle install
email
and password_digest
rails g model User email:string password_digest:string
rails db:migrate
to migrate it to the database. The email
stores the email address of the user. Also, password_digest
creates a password_digest field in the users table.app/models/user.rb
, add has_secure_password
and some validations.class User < ApplicationRecord
has_secure_password
validates :email , presence: true, uniqueness: true
end
rails g controller registrations new
app/controllers/registrations_controller.rb
class RegistrationsController < ApplicationController
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
session[:user_id] = @user.id
redirect_to root_path
else
render :new
end
end
private
def user_params
params.require(:user).permit(:email, :password, :password_confirmation)
end
end
new
action initializes a new object in the User model and stores it as an instance variable that can be accessed in the views. The create
action creates the user instance and sets its id to a session which redirects to the root_path
if successful and renders new
when it fails.app/views/registrations/new.html.erb.
<%= form_with model: @user, url: sign_up_path do |f| %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.label password_confirmation %>
<%= f.password_field :password_confirmation %>
<%= f.submit "Sign Up" %>
<% end %>
Rails.application.routes.draw do
get 'welcome', to: 'welcome#index'
root to: 'welcome#index'
resources :users
get 'sign_up', to: 'users#new'
post 'sign_up', to: 'users#create'
end
$ rails s
to start the development server and visit localhost:3000/sign_up
to create a new user.rails g controller sessions new create destroy
app/controllers/sessions_controller.rb
:class SessionsController < ApplicationController
def new
end
def create
user = User.find_by(email: params[:email])
if user.present? && user.authenticate(params[:password])
session[:user_id] = user.id
redirect_to root_path
else
render :new
end
end
def destroy
session[:user_id] = nil
redirect_to sign_in_path
end
end
create
method for SessionsController
finds the user based on the email in the database. If a user is present and the password matches, the id of the user instance is stored in a session and they are logged in. Otherwise, we will be redirected to the sign_in page.destroy
method sets the user session to nil and logs out the user.app/views/sessions/new.html.erb
, add:<h1>Sign In </h1>
<%= form_with url: sign_in_path do |f| %>
<%= f.label :Email %>
<%= f.text_field :email %>
<%= f.label :Password %>
<%= f.password_field :password %>
<%= f.submit "Sign in" %>
<% end %>
Rails.application.routes.draw do
get 'welcome', to: 'welcome#index'
root to: 'welcome#index'
resources :users
get 'sign_up', to: 'users#new'
post 'sign_up', to: 'users#create'
get 'sign_in', to: 'sessions#new'
post 'sign_in', to: 'sessions#create'
delete 'logout', to: 'sessions#destroy'
end
localhost:3000/sign_in
in the browser.app/controllers/application_controller.rb
to create a Current.user
class ApplicationController < ActionController::Base
before_action :set_current_user
def set_current_user
if session[:user_id]
Current.user = User.find_by(id: session[:user_id])
end
end
end
set_current_user
method will return the current user if it finds one or if there is a session present. Also, since all controllers inherit from the ApplicationController
, set_current_user
will be accessible in all the controllers.current.rb
file in app/models
and add the following:class Current < ActiveSupport::CurrentAttributes
attribute :user
end
Current.user
in our views. app/views/welcome/index.html.erb
and update it with the following:<h1>Welcome Page</h1>
<% if Current.user %>
Logged in as: Current.user.email<br>
<%= button_to "Sign Out", logout_path, method: :delete %>
<% else %>
<%= link_to "Sign up", sign_up_path %>
<%= link_to "Sign In", sign_in_path %>
<% end %>
Current.user
is present and provides a sign_out
button when signed in. Otherwise, a sign_up
and sign_in
link is seen.