rails 總結 一種簡單的驗證登入的方法總結 OK
阿新 • • 發佈:2019-02-19
這兩天學習了下CanCan的作用,順便把驗證使用者登入的功能學習了。rails下有功能強大的Devise,不過有時候使用簡單的方法就能達到預期的效果。
本文使用admin的登入作為例子講解
涉及到的檔案: admin_session_helper.rb , admin_sessions_controller.rb 兩個檔案總結的內容都寫在註釋上了,請認真
首先分析admin_sessions_controller.rb檔案,程式碼如下:
module Admin
class AdminSessionsController < Admin::ApplicationController
skip_authorization_check #跳過許可權驗證
skip_filter :authenticate_admin! #跳過登入驗證,要不就無法執行下面的程式碼
def new
@admin = Admin.new #新增Admin物件,但在create中沒有@admin.save這樣的操作,所以不會有admin被存入資料庫,
#create的作用只是從瀏覽器獲取輸入的 name,和 password。即:獲取params[:name],params[:password]
end
def create
admin = Admin.find_by(name: params[:admin][:name])
if admin.blank? || params[:admin][:name].blank? #對瀏覽器從輸入框獲取到的name,和password進行判斷。通過name找到資料庫中的相應記錄
return render js: " $('#js-admin-sign-in-validate').html('* 管理員不存在');" #先在資料庫中查詢是否有這個輸入的name
elsif params[:admin][:password].blank?
return render js: " $('#js-admin-sign-in-validate').html('* 密碼不能為空');"
elsif admin.password != params[:admin][:password] #password 不是admin的欄位,而是在model中的方法,最下面會貼出原因
return render js: " $('#js-admin-sign-in-validate').html('* 密碼錯誤');" #進一步判斷密碼是否為空,密碼是否和資料庫中相對應
end
admin_sign_in(admin.id, params[:remember_me].present?) #如果通過了上面的賬戶和密碼的判斷,則把這個admin的id傳到
return render js: " window.location.href='#{admin_root_path}';" #admin_sign_in 方法中,以及瀏覽器傳來的remember_me。此時,admin_sign_in 方法為true
end
#然後請檢視admin_session_helper.rb檔案內容
def destroy #退出登入操作 其實是admin_session_helper.rb 中的admin_sign_out起作用
admin_sign_out
redirect_to admin_root_path
end
end
private
def admin_params
params.require(:admin).permit(:password)
end
end
end
檔案程式碼: admin_session_helper.rb #這個helper檔案的作用總結為:1.三個方法:登入,登出,和用於判斷已登入的方法
module Admin # 2.將登入使用者的id,存入cookies Hash中儲存。
module AdminSessionHelper # 是 cookies.signed[]臨時儲存,關閉網頁後就不儲存登入資訊,
#還是cookies.permanent.signed[]長久儲存,關閉網頁回來後還有登入資訊
def session_key_admin_id
" ss_key" #定義一個Hash的key,只是起到名字的意義
end
def current_admin_id
@current_admin_id ||= cookies.signed[session_key_admin_id] #當前登入admin物件id 方法,便於後面程式的直接呼叫
end
def current_admin #當前登入admin物件 方法,便於後面程式中的直接呼叫
@current_admin ||= Admin.find_by(id: current_admin_id)
end
def admin_sign_in(admin_id, remember_me = false) #應該先看這個方法,再看其他方法。這裡就是admin.id傳了進來,存到了cookies Hash中
if remember_me #remember_me 用於看是否長久儲存登入資訊
cookies.permanent.signed[session_key_admin_id] = admin_id
else
cookies.signed[session_key_admin_id] = admin_id
end
end
def admin_sign_out # 登出操作方法,即在cookies Hash 中使用delete方法刪除相應的key,value也就被一起刪除了
return unless admin_signed_in? #如果admin_signed_in? 這個方法不為真,說明沒登入直接返回即可
cookies.delete session_key_admin_id # 刪除id操作,cookies中就沒有登入的id了,這樣就退出了
end
def admin_signed_in?
current_admin_id.present? # id能夠傳過來存到cookies Hash中存在就是已登入,不存在就是退出
end
def authenticate_admin! #該方法用於加入到需要判斷是否登入的頁面對應的controller中,
unless admin_signed_in? #before_action :authenticate_admin! 這裡起到驗證是否登入,為true,說明id存到cookies Hash中了,登入 成功。為false,則登入失敗
return redirect_to new_admin_admin_session_path
end
end
end
end
首先分析admin_sessions_controller.rb檔案,程式碼如下:
module Admin
class AdminSessionsController < Admin::ApplicationController
skip_authorization_check #跳過許可權驗證
skip_filter :authenticate_admin! #跳過登入驗證,要不就無法執行下面的程式碼
def new
@admin = Admin.new #新增Admin物件,但在create中沒有@admin.save這樣的操作,所以不會有admin被存入資料庫,
#create的作用只是從瀏覽器獲取輸入的 name,和 password。即:獲取params[:name],params[:password]
end
def create
admin = Admin.find_by(name: params[:admin][:name])
if admin.blank? || params[:admin][:name].blank? #對瀏覽器從輸入框獲取到的name,和password進行判斷。通過name找到資料庫中的相應記錄
return render js: " $('#js-admin-sign-in-validate').html('* 管理員不存在');" #先在資料庫中查詢是否有這個輸入的name
elsif params[:admin][:password].blank?
return render js: " $('#js-admin-sign-in-validate').html('* 密碼不能為空');"
elsif admin.password != params[:admin][:password] #password 不是admin的欄位,而是在model中的方法,最下面會貼出原因
return render js: " $('#js-admin-sign-in-validate').html('* 密碼錯誤');" #進一步判斷密碼是否為空,密碼是否和資料庫中相對應
end
admin_sign_in(admin.id, params[:remember_me].present?) #如果通過了上面的賬戶和密碼的判斷,則把這個admin的id傳到
return render js: " window.location.href='#{admin_root_path}';" #admin_sign_in 方法中,以及瀏覽器傳來的remember_me。此時,admin_sign_in 方法為true
end
#然後請檢視admin_session_helper.rb檔案內容
def destroy #退出登入操作 其實是admin_session_helper.rb 中的admin_sign_out起作用
admin_sign_out
redirect_to admin_root_path
end
end
private
def admin_params
params.require(:admin).permit(:password)
end
end
end
檔案程式碼: admin_session_helper.rb #這個helper檔案的作用總結為:1.三個方法:登入,登出,和用於判斷已登入的方法
module Admin # 2.將登入使用者的id,存入cookies Hash中儲存。
module AdminSessionHelper # 是 cookies.signed[]臨時儲存,關閉網頁後就不儲存登入資訊,
#還是cookies.permanent.signed[]長久儲存,關閉網頁回來後還有登入資訊
def session_key_admin_id
" ss_key" #定義一個Hash的key,只是起到名字的意義
end
def current_admin_id
@current_admin_id ||= cookies.signed[session_key_admin_id] #當前登入admin物件id 方法,便於後面程式的直接呼叫
end
def current_admin #當前登入admin物件 方法,便於後面程式中的直接呼叫
@current_admin ||= Admin.find_by(id: current_admin_id)
end
def admin_sign_in(admin_id, remember_me = false) #應該先看這個方法,再看其他方法。這裡就是admin.id傳了進來,存到了cookies Hash中
if remember_me #remember_me 用於看是否長久儲存登入資訊
cookies.permanent.signed[session_key_admin_id] = admin_id
else
cookies.signed[session_key_admin_id] = admin_id
end
end
def admin_sign_out # 登出操作方法,即在cookies Hash 中使用delete方法刪除相應的key,value也就被一起刪除了
return unless admin_signed_in? #如果admin_signed_in? 這個方法不為真,說明沒登入直接返回即可
cookies.delete session_key_admin_id # 刪除id操作,cookies中就沒有登入的id了,這樣就退出了
end
def admin_signed_in?
current_admin_id.present? # id能夠傳過來存到cookies Hash中存在就是已登入,不存在就是退出
end
def authenticate_admin! #該方法用於加入到需要判斷是否登入的頁面對應的controller中,
unless admin_signed_in? #before_action :authenticate_admin! 這裡起到驗證是否登入,為true,說明id存到cookies Hash中了,登入 成功。為false,則登入失敗
return redirect_to new_admin_admin_session_path
end
end
end
end