Berikut Ini adalah tutorial sederhana tentang penerapan Authorization atau Authentication dalam aplikasi Rails kamu. Disini Saya menggunakan versi 6.0 Ruby on Rails.
Sebagai catatan, ini adalah salah satu dari banyak cara untuk mengimplementasikan authentication, dan ini dimaksudkan untuk menampilkan pendekatan dasarnya saja.
Setup
Mari kita mulai dengan membuat project baru pada Ruby :
rails new session_latihan
cd session_latihan
Pada direktori root, kita akan menjalankan beberapa perintah untuk Controller dan Model pada Project kita. Sebelum kita melakukannya, mari kita bahas keseluruhan struktur.
Kita akan menggunakan satu Mode yaitu User. Dan kita akan membuat 2 Controller, satu untuk User dan satunya lagi untuk menangani custom route untuk mengelola session.
Model
UserController akan memiliki 2 route yakni new dan create. Sedangkan untuk SessionController akan memiliki 2 custom route untuk login dan welcome.
Sebagai tambahan untuk Route new dan create, View Page untuk create juga akan dihasilkan tetapi tidak akan kita gunakan, silahkan kamu hapus filenya nanti.
rails g controller users new create
rails g controller sessions new create login welcome
Installasi Gem Bcrypt
Pada database kita nanti, kita tidak akan menyimpan password berbasis plain text. Sebagai gantinya, kita akan menggabungkan Bcrypt untuk mengenkripsi password dan menyimpannya ke dalam database. Mari kita Install Gem Bcrypt nya terlebih dahulu.
gem install bcrypt
bundle install
Untuk Model User kita, kita akan menambahkan macro untuk mengolah Bcrypt pada field password nya.
class User < ApplicationRecord
has_secure_password
end
Mengatur Routes
Selanjutnya, mari siapkan route pada bagian config / routes.rb. Seperti yang mungkin kamu ketahui sekarang, route sudah ada karena kita menjalankan Rails g Controller sebelumnya. Kita dapat menghapus route-route tersebut dan menambahkan yang kita butuhkan saja.
Rails.application.routes.draw do
resources :users, only: [:new, :create]
get ‘login’, to: ‘sessions#new’
post ‘login’, to: ‘sessions#create’
get ‘welcome’, to: ‘sessions#welcome’
end
Welcome Page kita nanti akan kita isi dengan tombol Sign Up dan Login yang akan mengarahkan User ke form yang sesuai. Kemudian, halaman ini juga akan memeriksa apakah pengguna yang login, dan menampilkan nama mereka.
Welcome Page
Mari kita buka file views/sessions/welcome.index.erb dan tambahkan beberapa element didalamnya. Tombol SignUp akan mengarahkan Controller new User yang mana akan menampilkan form Sign up di new.html.erb. Sedangkan untuk Tombol loginnya, akan kita arahkan ke Session new Controller yang akan menampilkan login form .
<h1>Welcome</h1>
<%= button_to “Login”, ‘/login’, method: :get%>
<%= button_to “Sign Up”, ‘/users/new’, method: :get%>
SignUp
Perlu diIngat bahwa kita mengikuti konvensi Rails. @ user diinisialisasi dari Controller User sebagai @user = User.new. Dalam views / users / new.html.erb, kita akan menambahkan form_for seperti berikut:
<h1>Sign Up</h1>
<%= form_for @user do |f|%>
<%= f.label :username%><br>
<%= f.text_field :username%><br>
<%= f.label :password%><br>
<%= f.password_field :password%><br>
<%= f.submit %>
<%end%>
Saat di submit, kita akan redirected User Create Controller untuk menangani beberapa hal seperti ini :
def create @user = User.create(params.require(:user).permit(:username,
:password))
session[:user_id] = @user.id
redirect_to ‘/welcome’
end
Pertama, kita membuat contoh pengguna dan akhirnya mengarahkan ke halaman welcome. Kemudian kita perlu membuat method yang menangani informasi pengguna saat ini. Kita akan membuat method ini pada Application Controller untuk memastikan Controller lain memiliki akses ke method ini.
def current_user
User.find_by(id: session[:user_id])
end
Pada saat yang sama, kita ingin method dalam Application Controller kita tidak hanya untuk melacak pengguna saat ini, tetapi juga untuk memeriksa apakah mereka login atau tidak :
def logged_in?
!current_user.nil?
end
Untuk membuat kedua method diatas bisa diakses Views, kita perlu bantuan macro helper_method. Masih pada Application Controller, disini kita akan menambahkan :
class ApplicationController < ActionController::Base
helper_method :current_user
helper_method :logged_in?
def current_user
User.find_by(id: session[:user_id])
End
def logged_in?
!current_user.nil?end
end
Mari kita manfaatkan dua metode ini untuk menentukan apakah pengguna masuk dan juga menunjukkan nama pengguna apakah mereka sudah login atau belum. Buka kembali file views / sessios / welcome.html.erb dan tambahkan :
<h1>Welcome</h1>
<% if logged_in? %>
<h1>You are Logged In, <%= current_user.username %> </h1>
<%end%>
<%= button_to “Login”, ‘/login’, method: :get%>
<%= button_to “Sign Up”, ‘/users/new’, method: :get%>
Pertama, kita menempatkan Kondisi yang menggunakan metho logged_in?. Jika hasilnya true, itu berarti pengguna sudah login dan h1 akan merender. Pada tag h1, kita mengakses method current_user yang akan mengembalikan instance User, dan kita ingin menampilkan username instance.
Kita sekarang memiliki cara signup user dan menyimpannya di session mereka. Kita dapat menerapkan metode serupa untuk halaman login. Mari kita mulai dengan metodeSession Controller new, yang akan merender form login. Pada file views / sessions / new.html.erb tambahkan kode berikut :
<h1>Login</h1>
<%= form_tag ‘/login’ do %>
<%= label_tag :username%>
<%= text_field_tag :username %>
<%= label_tag :password%>
<%= password_field_tag :password%>
<%= submit_tag “Login”%>
<%end%>
Sekarang kita memiliki form login yang mirip dengan form Sign Up tetapi karena kita tidak akan membuat new user instance, kita akan menerapkan form_tag.
Di route tetapkan route pos untuk / login yang akan diarahkan ke metode buat Session Controller. Metode ini memiliki tanggung jawab untuk mencocokan User berdasarkan username yang disediakan oleh form.
def create
@user = User.find_by(username: params[:username])
if @user && @user.authenticate(params[:password])
sessions[:user_id] = @user.id
redirect_to ‘/welcome’
else
redirect_to ‘/login’
end
end
Jika kecocokan pengguna ditemukan, kita juga ingin memeriksa apakah password tersebut cocok atau tidak. Untuk melakukan ini, kita menggunakan metode Authenticate Bcrypt yang mengambil argumen dari params password.
Jika ada pengguna dan kata sandi cocok, id dari instance pengguna disimpan dalam satu sesi, dan mereka bisa login. Jika tidak, kita akan mengarahkan mereka kembali ke form login
Authorization / Authentication
Saat ini, kita memiliki halaman terbatas. Saat aplikasi kita semakin besar, kita tentunya tidak ingin pengguna yang tidak terdaftar mengakses route tertentu. Namun, kita ingin beberapa route dapat diakses untuk memungkinkan pengguna SignUp atau Login. Untuk melakukannya, kita perlu menambahkan metode di banyak Controller.
Untuk menguji ini, kita juga akan menambahkan halaman tampilan tambahan yang hanya dapat diakses jika pengguna masuk serta metode controller dan route untuk mengakses halaman itu. Di Session Controller , mari tambahkan metode page_requires_login.
Secara bersamaan, mari kita buat page_requires_login.html.erb di views / sessions dan di route kita, tambahkan authorized route di config / routes.rb:
Rails.application.routes.draw do
resources :users, only: [:new, :create]
get ‘login’, to: ‘sessions#new’
post ‘login’, to: ‘sessions#create’
get ‘welcome’, to: ‘sessions#welcome’
get ‘authorized’, to:
‘sessions#page_requires_login’
end
Kita ingin setiap route kecuali / authorized untuk dapat diakses oleh pengguna yang tidak terdaftar. Tapi kita belum mendefinisikan tindakan ini. Mari kita bernavigasi ke Applications Controller, tambahkan metode lain yang di authorized dan makro lain before_action , atur menjadi authorized.
class ApplicationController < ActionController::Base
before_action :authorized
helper_method :current_user
helper_method :logged_in?
def current_user
User.find_by(id: session[:user_id])
End
def logged_in?
!current_user.nil?
end
def authorized
redirect_to ‘/welcome’ unless logged_in?
end
end
Makro before_action mengharuskan metode yang diotorisasi untuk berjalan sebelum tindakan lain diambil. Dalam hal ini, kecuali jika pengguna masuk, pengguna akan selalu diarahkan ke halaman welcome.
Namun, kita ingin metode yang memungkinkan pengguna untuk login tersedia. Pertama, mari kita menavigasi kembali ke User Controller dan menambahkan makro skip_before_action berikut:
class UsersController < ApplicationController
skip_before_action :authorized, only: [:new, :create]
def new
@user = User.new
End
def create
@user = User.create(params.require(:user).permit(:username,
:password))
session[:user_id] = @user.id
redirect_to ‘/welcome’
end
end
Makro ini memungkinkan dua metode untuk melewati persyaratan metode yang diotorisasi. Kita juga akan menerapkan makro ke Session Controller, tetapi kita akan menambahkan welcome ke metode karena kami ingin dapat mengakses halaman welcome.
class SessionsController < ApplicationController
skip_before_action :authorized, only: [:new, :create, :welcome]
def new
end
def login
end
def create
@user = User.find_by(username: params[:username])
if @user && @user.authenticate(params[:password])
sessions[:user_id] = @user.id
redirect_to ‘/welcome’
else
redirect_to ‘/login’
end
end
def page_requires_login
end
end
Sekarang, mari kita periksa apakah metode kita berfungsi. Mari kita kembali ke views / sesion / page_requires_login.html.erb yang telah kita buat sebelumnya.
Kami hanya akan menambahkan tag h1. Tujuan dari halaman ini adalah untuk memeriksa apakah kita hanya dapat mengaksesnya jika kita login, kalau tidak kita akan diarahkan ke halaman welcome.
<h1>You have access to this page, <%= current_user.username %></h1>
Jika kita mencoba mengakses / diotorisasi tanpa login, kita akan diarahkan kembali ke halaman welome. Kita telah berhasil menerapkan otentikasi / otorisasi ke dalam aplikasi kita.
Kita tidak akan membahas fitur logout dalam panduan ini, tetapi idenya adalah untuk menghapus session [: user_id] dan mengarahkan pengguna kembali ke halaman welcome.
Sumber : levelup.gitconnected.com