This is a post following Last time! This time, I will summarize the implementation of the login function! !!
First, create a User model.
rails g model User name:string email:string password_digest: string
Do this and rails db: migrate. password_digest is a naming convention when using the standard Rails function has_secure_password.
The password_digest created earlier contains an irreversible hash of the entered password. If you save the password in the DB as it is, it is very dangerous if it leaks, so doing so will prevent leakage. Therefore, we will introduce a gem called "bcrypt" that provides a hash function.
gem 'bcrypt', '~> 3.1.7'
After adding to the gemfile, bundle install.
After introducing gem, there is only one thing to do. Add the following.
User.rb
has_secure_password
You're ready to go! Next, we will implement the controller.
The login function is realized by holding the user's id in the session [: user_id]. First, create sessions_controller.rb with a new method for login.
rails g controller Sessions new
This new action is the transition to the login screen. This time, I made the following form.
h1 login
= form_with scope: :session, local: true do |f|
.form-group
= f.label :email, 'mail address'
= f.text_field :email, class: 'form-control', id: 'session_email'
.form-group
= f.label :password, 'password'
= f.password_field :password, class: 'form-control', id: 'session_password'
= f.submit 'log in', class: 'btn btn-primary'
Login process is performed based on the sent parameters. First, edit the routes.
config/routes.rb
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create' //Add here
controllers/sessions_controller.rb
def create
//Search the users table for a matching email address.
user = User.find_by(email: session_params[:email])
//If the email address exists, password authentication is performed with the authenticate method.
if user&.authenticate(session_params[:password])
//After successful authentication, hold the user's id in session.
session[:user_id] = user.id
redirect_to root_url, notice: 'You are now logged.'
else
render :new
end
end
private
def session_params
params.require(:session).permit(:email, :password)
end
You can get the user's information with the following code.
User.find_by(id: session[:user_id])
However, it is troublesome to write this every time, so define a variable called current_user in application.rb so that it can be used from any controller. Also, specify helper_method and write it so that it can be used in view!
controllers/application.rb
helper_method :current_user
private
def current_user
// session[:user_id]If there is a value in (if you are logged in),@current_Store login user information in user
@current_user ||= User.find_by(id: session[:user_id]) if session[:user_id]
end
The logout function is realized by deleting session [: user_id].
routes.rb
delete 'logout', to: 'session#destroy'
session_controller.rb
def destroy
reset_session
redirect_to root_url, notice: 'logged out'
end
The view looks like this
application.html.slim
- if current_user
li.nav-item= link_to 'Log out', logout_path, method: :delete, class: 'nav-link'
- else
li.nav-item= link_to 'Login', login_path, class: 'nav-link'
If you want to disable all features without logging in, add a method to application_controller.
application.rb
before_action :login_required
private
def login_required
// current_user is nil(Not logged in)When redirecting to the login screen
redirect_to login_url unless current_user
end
In the case of the above description, it will be a chaotic situation that you can not see the login screen unless you log in. Therefore, only session_controller removes this restriction.
session_controller.rb
skip_before_action :login_required
-Ruby on Rails 5 Quick Learning Practice Guide that can be used in the field
Recommended Posts