Devise เป็นโซลูชันการตรวจสอบสิทธิ์ที่ยืดหยุ่นสำหรับ Rails ที่ใช้ Warden มัน:
ประกอบด้วย 10 โมดูล:
Devise Wiki มีข้อมูลเพิ่มเติมมากมายเกี่ยวกับ Devise รวมถึงบทความ "วิธีใช้" และคำตอบสำหรับคำถามที่พบบ่อยที่สุด โปรดเรียกดู Wiki หลังจากเสร็จสิ้น README นี้:
https://github.com/heartcombo/devise/wiki
หากคุณพบปัญหากับ Devise เราต้องการทราบเกี่ยวกับเรื่องนี้ อย่างไรก็ตาม เราขอให้คุณโปรดอ่านหลักเกณฑ์เหล่านี้ก่อนที่จะส่งรายงานข้อผิดพลาด:
https://github.com/heartcombo/devise/wiki/Bug-reports
หากคุณพบข้อบกพร่องที่เกี่ยวข้องกับความปลอดภัย โปรด อย่า ใช้เครื่องมือติดตามปัญหา GitHub ส่งอีเมลไปที่ [email protected]
หากคุณมีคำถาม ความคิดเห็น หรือข้อกังวลใดๆ โปรดใช้ StackOverflow แทนเครื่องมือติดตามปัญหา GitHub:
http://stackoverflow.com/questions/tagged/devise
รายชื่ออีเมลที่เลิกใช้แล้วยังสามารถอ่านได้ต่อไป
https://groups.google.com/group/plataformatec-devise
คุณสามารถดูเอกสาร Devise ในรูปแบบ RDoc ได้ที่นี่:
http://rubydoc.info/github/heartcombo/devise/main/frames
หากคุณต้องการใช้ Devise กับ Rails เวอร์ชันก่อนหน้า คุณสามารถเรียกใช้ "เซิร์ฟเวอร์ gem" จากบรรทัดคำสั่งได้เสมอหลังจากที่คุณติดตั้ง gem เพื่อเข้าถึงเอกสารเก่า
มีแอปพลิเคชันตัวอย่างบางส่วนบน GitHub ที่สาธิตคุณสมบัติต่างๆ ของ Devise ด้วย Rails เวอร์ชันต่างๆ คุณสามารถดูได้ที่นี่:
https://github.com/heartcombo/devise/wiki/Example-Applications
ชุมชนของเราได้สร้างส่วนขยายจำนวนหนึ่งที่เพิ่มฟังก์ชันการทำงานที่เหนือกว่าสิ่งที่รวมอยู่ใน Devise คุณสามารถดูรายการส่วนขยายที่มีอยู่และเพิ่มส่วนขยายของคุณเองได้ที่นี่:
https://github.com/heartcombo/devise/wiki/Extensions
เราหวังว่าคุณจะพิจารณาการมีส่วนร่วมกับ Devise โปรดอ่านภาพรวมสั้นๆ นี้เพื่อดูข้อมูลบางอย่างเกี่ยวกับวิธีเริ่มต้นใช้งาน:
https://github.com/heartcombo/devise/wiki/การมีส่วนร่วม
โดยปกติคุณจะต้องการเขียนการทดสอบสำหรับการเปลี่ยนแปลงของคุณ หากต้องการรันชุดทดสอบ ให้ไปที่ไดเร็กทอรีระดับบนสุดของ Devise แล้วรัน bundle install
และ bin/test
Devise ใช้งานได้กับ Ruby และ Rails หลายเวอร์ชัน และ ActiveRecord และ Mongoid ORM ซึ่งหมายความว่าคุณสามารถรันชุดทดสอบด้วยตัวดัดแปลงบางตัว: DEVISE_ORM
และ BUNDLE_GEMFILE
เนื่องจาก Devise รองรับทั้ง Mongoid และ ActiveRecord เราจึงใช้ตัวแปรนี้ในการรันโค้ดเฉพาะสำหรับแต่ละ ORM ค่าเริ่มต้นของ DEVISE_ORM
คือ active_record
หากต้องการรันการทดสอบสำหรับ Mongoid คุณสามารถผ่าน mongoid
:
DEVISE_ORM=mongoid bin/test
==> Devise.orm = :mongoid
เมื่อรันการทดสอบสำหรับ Mongoid คุณจะต้องมีเซิร์ฟเวอร์ MongoDB (เวอร์ชัน 2.0 หรือใหม่กว่า) ทำงานบนระบบของคุณ
โปรดทราบว่าเอาต์พุตคำสั่งจะแสดงค่าตัวแปรที่ใช้
เราสามารถใช้ตัวแปรนี้เพื่อบอก Bundler ว่าควรใช้ Gemfile ใด (แทนที่จะเป็นตัวแปรในไดเร็กทอรีปัจจุบัน) ภายในไดเร็กทอรี gemfiles เรามีหนึ่งรายการสำหรับ Rails แต่ละเวอร์ชันที่เรารองรับ เมื่อคุณส่งคำขอดึงข้อมูลมาให้เรา อาจเป็นไปได้ว่าชุดการทดสอบใช้งานบางส่วนเสียหาย หากเป็นกรณีนี้ คุณสามารถจำลองสภาพแวดล้อมเดียวกันได้โดยใช้ตัวแปร BUNDLE_GEMFILE
ตัวอย่างเช่น หากการทดสอบล้มเหลวโดยใช้ Ruby 3.0.0 และ Rails 6.0 คุณสามารถทำสิ่งต่อไปนี้:
rbenv shell 3.0.0 # or rvm use 3.0.0
BUNDLE_GEMFILE=gemfiles/Gemfile-rails-6-0 bundle install
BUNDLE_GEMFILE=gemfiles/Gemfile-rails-6-0 bin/test
คุณยังสามารถรวมทั้งสองอย่างเข้าด้วยกันได้หากการทดสอบล้มเหลวสำหรับ Mongoid:
BUNDLE_GEMFILE=gemfiles/Gemfile-rails-6-0 bundle install
BUNDLE_GEMFILE=gemfiles/Gemfile-rails-6-0 DEVISE_ORM=mongoid bin/test
Devise ใช้ Mini Test เป็นกรอบการทดสอบ
bin/test
bin/test test/models/trackable_test.rb
bin/test test/models/trackable_test.rb:16
หากคุณกำลังสร้างแอปพลิเคชัน Rails แรก เราขอแนะนำให้คุณ อย่า ใช้ Devise Devise ต้องการความเข้าใจอย่างดีเกี่ยวกับ Rails Framework ในกรณีเช่นนี้ เราขอแนะนำให้คุณเริ่มระบบการตรวจสอบสิทธิ์แบบง่ายตั้งแต่เริ่มต้น ต่อไปนี้เป็นแหล่งข้อมูลบางส่วนที่ควรช่วยคุณในการเริ่มต้น:
เมื่อคุณเข้าใจ Rails และกลไกการตรวจสอบความถูกต้องแล้ว เรารับรองว่า Devise จะยินดีเป็นอย่างยิ่งที่ได้ร่วมงานด้วย -
Devise 4.0 ใช้งานได้กับ Rails 6.0 เป็นต้นไป วิ่ง:
bundle add devise
ถัดไปคุณต้องเรียกใช้ตัวสร้าง:
rails generate devise:install
ณ จุดนี้ คำแนะนำจำนวนหนึ่งจะปรากฏในคอนโซล ในคำแนะนำเหล่านี้ คุณจะต้องตั้งค่าตัวเลือก URL เริ่มต้นสำหรับจดหมาย Devise ในแต่ละสภาพแวดล้อม นี่คือการกำหนดค่าที่เป็นไปได้สำหรับ config/environments/development.rb
:
config . action_mailer . default_url_options = { host : 'localhost' , port : 3000 }
เครื่องกำเนิดไฟฟ้าจะติดตั้งตัวเริ่มต้นซึ่งอธิบายตัวเลือกการกำหนดค่าทั้งหมดของ Devise มี ความจำเป็น ที่คุณจะต้องดูมัน เมื่อเสร็จแล้ว คุณก็พร้อมที่จะเพิ่ม Devise ให้กับโมเดลใดๆ ของคุณโดยใช้ตัวสร้าง
ในคำสั่งต่อไปนี้ คุณจะแทนที่ MODEL
ด้วยชื่อคลาสที่ใช้สำหรับผู้ใช้แอปพลิเคชัน (บ่อยครั้งคือ User
แต่อาจเป็น Admin
ก็ได้) สิ่งนี้จะสร้างโมเดล (หากไม่มี) และกำหนดค่าด้วยโมดูล Devise เริ่มต้น ตัวสร้างยังกำหนดค่าไฟล์ config/routes.rb
ของคุณให้ชี้ไปที่คอนโทรลเลอร์ Devise
rails generate devise MODEL
ถัดไป ตรวจสอบ MODEL เพื่อดูตัวเลือกการกำหนดค่าเพิ่มเติมที่คุณอาจต้องการเพิ่ม เช่น ยืนยันได้หรือล็อคได้ หากคุณเพิ่มตัวเลือก ตรวจสอบให้แน่ใจว่าได้ตรวจสอบไฟล์การโยกย้าย (สร้างโดยตัวสร้างหาก ORM ของคุณรองรับ) และยกเลิกการใส่เครื่องหมายข้อคิดเห็นในส่วนที่เหมาะสม ตัวอย่างเช่น หากคุณเพิ่มตัวเลือกที่ยืนยันได้ในโมเดล คุณจะต้องยกเลิกหมายเหตุส่วนที่ยืนยันได้ในการย้ายข้อมูล
จากนั้นรัน rails db:migrate
คุณควรรีสตาร์ทแอปพลิเคชันของคุณหลังจากเปลี่ยนตัวเลือกการกำหนดค่าของ Devise (รวมถึงการหยุดสปริง) มิฉะนั้นคุณจะพบข้อผิดพลาดแปลกๆ เช่น ผู้ใช้ไม่สามารถเข้าสู่ระบบและกำหนดเส้นทางผู้ช่วยไม่ได้
Devise จะสร้างตัวช่วยเพื่อใช้ภายในคอนโทรลเลอร์และมุมมองของคุณ หากต้องการตั้งค่าคอนโทรลเลอร์ด้วยการตรวจสอบสิทธิ์ผู้ใช้ เพียงเพิ่มสิ่งนี้ before_action (สมมติว่ารุ่นอุปกรณ์ของคุณคือ 'ผู้ใช้'):
before_action :authenticate_user!
สำหรับ Rails 5 โปรดทราบว่า protect_from_forgery
จะไม่ขึ้นหน้าห่วงโซ่ before_action
อีกต่อไป ดังนั้นหากคุณตั้งค่า authenticate_user
ก่อน protect_from_forgery
คำขอของคุณจะส่งผลให้ "ไม่สามารถตรวจสอบความถูกต้องของโทเค็น CSRF ได้" หากต้องการแก้ไขปัญหานี้ ให้เปลี่ยนลำดับที่คุณเรียก หรือใช้ protect_from_forgery prepend: true
หากโมเดลอุปกรณ์ของคุณเป็นอย่างอื่นที่ไม่ใช่ User ให้แทนที่ "_user" ด้วย "_yourmodel" ตรรกะเดียวกันนี้ใช้กับคำแนะนำด้านล่าง
หากต้องการตรวจสอบว่าผู้ใช้ลงชื่อเข้าใช้หรือไม่ ให้ใช้ตัวช่วยต่อไปนี้:
user_signed_in?
สำหรับผู้ใช้ที่ลงชื่อเข้าใช้ปัจจุบัน ตัวช่วยนี้พร้อมใช้งาน:
current_user
คุณสามารถเข้าถึงเซสชันสำหรับขอบเขตนี้:
user_session
หลังจากลงชื่อเข้าใช้ผู้ใช้ ยืนยันบัญชีหรืออัปเดตรหัสผ่าน Devise จะค้นหาเส้นทางรูทที่กำหนดขอบเขตเพื่อเปลี่ยนเส้นทางไป ตัวอย่างเช่น เมื่อใช้ทรัพยากร :user
จะใช้ user_root_path
หากมีอยู่ มิฉะนั้น จะใช้ root_path
เริ่มต้น ซึ่งหมายความว่าคุณต้องตั้งค่ารูทภายในเส้นทางของคุณ:
root to : 'home#index'
คุณยังสามารถแทนที่ after_sign_in_path_for
และ after_sign_out_path_for
เพื่อปรับแต่ง hook การเปลี่ยนเส้นทางของคุณได้
โปรดสังเกตว่าหากโมเดล Devise ของคุณถูกเรียกว่า Member
แทนที่จะเป็น User
ดังนั้นตัวช่วยที่มีอยู่คือ:
before_action :authenticate_member!
member_signed_in?
current_member
member_session
วิธี Devise ในโมเดลของคุณยอมรับตัวเลือกบางอย่างเพื่อกำหนดค่าโมดูลด้วย ตัวอย่างเช่น คุณสามารถเลือกต้นทุนของอัลกอริธึมการแฮชด้วย:
devise :database_authenticatable , :registerable , :confirmable , :recoverable , stretches : 13
นอกจากนี้ :stretches
คุณสามารถกำหนด :pepper
, :encryptor
, :confirm_within
, :remember_for
, :timeout_in
, :unlock_in
ท่ามกลางตัวเลือกอื่น ๆ สำหรับรายละเอียดเพิ่มเติม โปรดดูไฟล์ Initializer ที่สร้างขึ้นเมื่อคุณเรียกใช้ตัวสร้าง "devise:install" ที่อธิบายไว้ข้างต้น ไฟล์นี้มักจะอยู่ที่ /config/initializers/devise.rb
API ฆ่าเชื้อพารามิเตอร์มีการเปลี่ยนแปลงสำหรับ Devise 4
สำหรับเวอร์ชัน Devise ก่อนหน้า โปรดดู https://github.com/heartcombo/devise/tree/3-stable#strong-parameters
เมื่อคุณปรับแต่งมุมมองของคุณเอง คุณอาจจะต้องเพิ่มแอตทริบิวต์ใหม่ลงในแบบฟอร์ม Rails 4 ย้ายการฆ่าเชื้อพารามิเตอร์จากโมเดลไปยังคอนโทรลเลอร์ ทำให้ Devise จัดการข้อกังวลนี้ที่คอนโทรลเลอร์เช่นกัน
มีเพียงสามการกระทำใน Devise ที่อนุญาตให้ชุดพารามิเตอร์ใดๆ ส่งผ่านไปยังโมเดลได้ ดังนั้นจึงต้องมีการฆ่าเชื้อ ชื่อและพารามิเตอร์เริ่มต้นที่อนุญาตคือ:
sign_in
( Devise::SessionsController#create
) - อนุญาตเฉพาะคีย์การรับรองความถูกต้อง (เช่น email
)sign_up
( Devise::RegistrationsController#create
) - อนุญาตคีย์การตรวจสอบสิทธิ์พร้อม password
และ password_confirmation
account_update
( Devise::RegistrationsController#update
) - อนุญาตให้ใช้คีย์การตรวจสอบสิทธิ์พร้อม password
, password_confirmation
และ current_password
ในกรณีที่คุณต้องการอนุญาตพารามิเตอร์เพิ่มเติม (lazy way™) คุณสามารถทำได้โดยใช้คำสั่งง่ายๆ before action ใน ApplicationController
ของคุณ :
class ApplicationController < ActionController :: Base
before_action :configure_permitted_parameters , if : :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer . permit ( :sign_up , keys : [ :username ] )
end
end
ข้อมูลข้างต้นใช้ได้กับฟิลด์เพิ่มเติมใดๆ ที่พารามิเตอร์เป็นประเภทสเกลาร์แบบธรรมดา หากคุณมีแอตทริบิวต์ที่ซ้อนกัน (เช่นคุณกำลังใช้ accepts_nested_attributes_for
) คุณจะต้องบอกอุปกรณ์เกี่ยวกับการซ้อนและประเภทเหล่านั้น:
class ApplicationController < ActionController :: Base
before_action :configure_permitted_parameters , if : :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer . permit ( :sign_up , keys : [ :first_name , :last_name , address_attributes : [ :country , :state , :city , :area , :postal_code ] ] )
end
end
Devise ช่วยให้คุณสามารถเปลี่ยนค่าเริ่มต้นของ Devise ได้อย่างสมบูรณ์หรือเรียกใช้พฤติกรรมที่กำหนดเองโดยส่งบล็อก:
หากต้องการอนุญาตค่าสเกลาร์อย่างง่ายสำหรับชื่อผู้ใช้และอีเมล ให้ใช้สิ่งนี้
def configure_permitted_parameters
devise_parameter_sanitizer . permit ( :sign_in ) do | user_params |
user_params . permit ( :username , :email )
end
end
หากคุณมีช่องทำเครื่องหมายที่แสดงบทบาทที่ผู้ใช้อาจทำในการลงทะเบียน เบราว์เซอร์จะส่งช่องทำเครื่องหมายที่เลือกเหล่านั้นเป็นอาร์เรย์ อาร์เรย์ไม่ใช่หนึ่งในสเกลาร์ที่อนุญาตของพารามิเตอร์ที่แข็งแกร่ง ดังนั้นเราจึงจำเป็นต้องกำหนดค่า Devise ด้วยวิธีต่อไปนี้:
def configure_permitted_parameters
devise_parameter_sanitizer . permit ( :sign_up ) do | user_params |
user_params . permit ( { roles : [ ] } , :email , :password , :password_confirmation )
end
end
สำหรับรายการสเกลาร์ที่อนุญาต และวิธีการประกาศคีย์ที่อนุญาตในแฮชและอาร์เรย์ที่ซ้อนกัน โปรดดู
https://github.com/rails/strong_parameters#nested-parameters
หากคุณมี Devise หลายรุ่น คุณอาจต้องการตั้งค่าตัวฆ่าเชื้อพารามิเตอร์ที่แตกต่างกันในแต่ละรุ่น ในกรณีนี้ เราขอแนะนำให้สืบทอดจาก Devise::ParameterSanitizer
และเพิ่มตรรกะของคุณเอง:
class User :: ParameterSanitizer < Devise :: ParameterSanitizer
def initialize ( * )
super
permit ( :sign_up , keys : [ :username , :email ] )
end
end
จากนั้นกำหนดค่าคอนโทรลเลอร์ของคุณให้ใช้งาน:
class ApplicationController < ActionController :: Base
protected
def devise_parameter_sanitizer
if resource_class == User
User :: ParameterSanitizer . new ( User , :user , params )
else
super # Use the default one
end
end
end
ตัวอย่างข้างต้นจะแทนที่พารามิเตอร์ที่อนุญาตสำหรับผู้ใช้ให้เป็นทั้ง :username
และ :email
วิธีที่ไม่ขี้เกียจในการกำหนดค่าพารามิเตอร์คือการกำหนดตัวกรองก่อนด้านบนในคอนโทรลเลอร์แบบกำหนดเอง เรามีรายละเอียดวิธีกำหนดค่าและปรับแต่งคอนโทรลเลอร์ในบางส่วนด้านล่าง
เราสร้าง Devise เพื่อช่วยให้คุณพัฒนาแอปพลิเคชันที่ใช้การรับรองความถูกต้องได้อย่างรวดเร็ว อย่างไรก็ตาม เราไม่ต้องการขัดขวางคุณเมื่อคุณต้องการปรับแต่งมัน
เนื่องจาก Devise เป็นเครื่องมือ มุมมองทั้งหมดจึงถูกบรรจุอยู่ภายในอัญมณี มุมมองเหล่านี้จะช่วยให้คุณเริ่มต้นได้ แต่หลังจากผ่านไประยะหนึ่ง คุณอาจต้องการเปลี่ยนแปลงมุมมองเหล่านี้ หากเป็นกรณีนี้ คุณเพียงแค่ต้องเรียกใช้ตัวสร้างต่อไปนี้ และมันจะคัดลอกมุมมองทั้งหมดไปยังแอปพลิเคชันของคุณ:
rails generate devise:views
หากคุณมีโมเดล Devise มากกว่าหนึ่งรุ่นในแอปพลิเคชันของคุณ (เช่น User
และ Admin
) คุณจะสังเกตเห็นว่า Devise ใช้มุมมองเดียวกันสำหรับทุกรุ่น โชคดีที่ Devise เสนอวิธีง่ายๆ ในการปรับแต่งมุมมอง สิ่งที่คุณต้องทำคือตั้งค่า config.scoped_views = true
ภายในไฟล์ config/initializers/devise.rb
หลังจากดำเนินการดังกล่าว คุณจะสามารถดูข้อมูลพร็อพเพอร์ตี้ตามบทบาท เช่น users/sessions/new
และ admins/sessions/new
หากไม่พบมุมมองภายในขอบเขต Devise จะใช้มุมมองเริ่มต้นที่ devise/sessions/new
คุณยังสามารถใช้ตัวสร้างเพื่อสร้างมุมมองที่กำหนดขอบเขตได้:
rails generate devise:views users
หากคุณต้องการสร้างมุมมองเพียงไม่กี่ชุด เช่นเดียวกับชุดของโมดูล registerable
และ confirmable
คุณสามารถส่งรายการมุมมองไปยังตัวสร้างด้วยแฟล็ก -v
rails generate devise:views -v registrations confirmations
หากการปรับแต่งในระดับมุมมองยังไม่เพียงพอ คุณสามารถปรับแต่งคอนโทรลเลอร์แต่ละตัวได้โดยทำตามขั้นตอนเหล่านี้:
สร้างคอนโทรลเลอร์แบบกำหนดเองของคุณโดยใช้ตัวสร้างซึ่งต้องมีขอบเขต:
rails generate devise:controllers [scope]
หากคุณระบุ users
เป็นขอบเขต ตัวควบคุมจะถูกสร้างขึ้นใน app/controllers/users/
และตัวควบคุมเซสชันจะมีลักษณะดังนี้:
class Users :: SessionsController < Devise :: SessionsController
# GET /resource/sign_in
# def new
# super
# end
...
end
ใช้แฟล็ก -c
เพื่อระบุคอนโทรลเลอร์ตั้งแต่หนึ่งตัวขึ้นไป ตัวอย่างเช่น rails generate devise:controllers users -c sessions
บอกให้เราเตอร์ใช้คอนโทรลเลอร์นี้:
devise_for :users , controllers : { sessions : 'users/sessions' }
แนะนำ แต่ไม่จำเป็น: คัดลอก (หรือย้าย) มุมมองจาก devise/sessions
ไปยัง users/sessions
Rails จะใช้มุมมองจาก devise/sessions
ต่อไปเนื่องจากการสืบทอด หากคุณข้ามขั้นตอนนี้ แต่การมีมุมมองที่ตรงกับคอนโทรลเลอร์จะทำให้สิ่งต่าง ๆ สอดคล้องกัน
สุดท้าย ให้เปลี่ยนแปลงหรือขยายการดำเนินการของคอนโทรลเลอร์ที่ต้องการ
คุณสามารถแทนที่การกระทำของคอนโทรลเลอร์ได้อย่างสมบูรณ์:
class Users :: SessionsController < Devise :: SessionsController
def create
# custom sign-in code
end
end
หรือคุณสามารถเพิ่มพฤติกรรมใหม่ลงไปได้:
class Users :: SessionsController < Devise :: SessionsController
def create
super do | resource |
BackgroundWorker . trigger ( resource )
end
end
end
สิ่งนี้มีประโยชน์สำหรับการทริกเกอร์งานเบื้องหลังหรือการบันทึกเหตุการณ์ระหว่างการดำเนินการบางอย่าง
โปรดจำไว้ว่า Devise ใช้ข้อความแฟลชเพื่อแจ้งให้ผู้ใช้ทราบว่าการลงชื่อเข้าใช้สำเร็จหรือไม่สำเร็จ Devise คาดว่าแอปพลิเคชันของคุณจะเรียก flash[:notice]
และ flash[:alert]
ตามความเหมาะสม อย่าพิมพ์แฟลชแฮชทั้งหมด ให้พิมพ์เฉพาะคีย์ที่กำหนดเท่านั้น ในบางกรณี Devise จะเพิ่มคีย์ :timedout
ให้กับแฟลชแฮช ซึ่งไม่ได้มีไว้สำหรับการแสดงผล ลบคีย์นี้ออกจากแฮชหากคุณต้องการพิมพ์แฮชทั้งหมด
Devise ยังมาพร้อมกับเส้นทางเริ่มต้นด้วย หากคุณต้องการปรับแต่งสิ่งเหล่านี้ คุณควรจะสามารถทำได้ผ่านเมธอด devise_for ยอมรับตัวเลือกต่างๆ เช่น :class_name, :path_prefix และอื่นๆ รวมถึงความเป็นไปได้ในการเปลี่ยนชื่อพาธสำหรับ I18n:
devise_for :users , path : 'auth' , path_names : { sign_in : 'login' , sign_out : 'logout' , password : 'secret' , confirmation : 'verification' , unlock : 'unblock' , registration : 'register' , sign_up : 'cmon_let_me_in' }
อย่าลืมตรวจสอบเอกสารประกอบ devise_for
เพื่อดูรายละเอียด
หากคุณต้องการการปรับแต่งที่ลึกซึ้งยิ่งขึ้น เช่น เพื่ออนุญาต "/sign_in" นอกเหนือจาก "/users/sign_in" สิ่งที่คุณต้องทำคือสร้างเส้นทางของคุณตามปกติและรวมเส้นทางเหล่านั้นไว้ในบล็อก devise_scope
ในเราเตอร์:
devise_scope :user do
get 'sign_in' , to : 'devise/sessions#new'
end
ด้วยวิธีนี้ คุณจะบอกให้ Devise ใช้ขอบเขต :user
เมื่อเข้าถึง "/sign_in" ประกาศ devise_scope
ก็มีนามแฝง as
ในเราเตอร์ของคุณ
โปรดทราบ: คุณยังคงต้องเพิ่ม devise_for
ในเส้นทางของคุณเพื่อที่จะใช้วิธีการช่วยเหลือ เช่น current_user
devise_for :users , skip : :all
Devise ทำงานร่วมกับ Hotwire/Turbo โดยปฏิบัติต่อคำขอดังกล่าวเสมือนเป็นการนำทาง และกำหนดค่าการตอบสนองบางอย่างสำหรับข้อผิดพลาดและการเปลี่ยนเส้นทางเพื่อให้ตรงกับลักษณะการทำงานที่คาดหวัง แอปใหม่จะถูกสร้างขึ้นด้วยการกำหนดค่าการตอบสนองต่อไปนี้ตามค่าเริ่มต้น และแอปที่มีอยู่อาจเลือกใช้โดยการเพิ่มการกำหนดค่าให้กับตัวเตรียมใช้งาน Devise:
Devise . setup do | config |
# ...
# When using Devise with Hotwire/Turbo, the http status for error responses
# and some redirects must match the following. The default in Devise for existing
# apps is `200 OK` and `302 Found` respectively, but new apps are generated with
# these new defaults that match Hotwire/Turbo behavior.
# Note: These might become the new default in future versions of Devise.
config . responder . error_status = :unprocessable_entity
config . responder . redirect_status = :see_other
end
สิ่งสำคัญ : การตอบกลับแบบกำหนดเองเหล่านี้กำหนดให้เวอร์ชัน gem responders
เป็น 3.1.0
หรือสูงกว่า โปรดตรวจสอบให้แน่ใจว่าคุณได้อัปเดตหากคุณจะใช้การกำหนดค่านี้ ตรวจสอบคู่มือการอัปเกรดนี้สำหรับข้อมูลเพิ่มเติม
หมายเหตุ : การกำหนดค่าสถานะข้างต้นอาจกลายเป็นค่าเริ่มต้นสำหรับ Devise ในรุ่นอนาคต
มีการเปลี่ยนแปลงอื่นๆ อีกสองสามอย่างที่คุณอาจต้องทำในแอปของคุณเพื่อทำงานร่วมกับ Hotwire/Turbo หากคุณย้ายจาก Rails-ujs:
data-confirm
ที่เพิ่ม modal การยืนยันให้กับปุ่ม/แบบฟอร์มก่อนที่จะส่งจำเป็นต้องเปลี่ยนเป็น data-turbo-confirm
เพื่อให้ Turbo จัดการสิ่งเหล่านั้นได้อย่างเหมาะสมdata-method
ที่กำหนดวิธีการร้องขอสำหรับการส่งลิงก์จำเป็นต้องเปลี่ยนเป็น data-turbo-method
สิ่งนี้ไม่จำเป็นสำหรับ button_to
หรือ form
เนื่องจาก Turbo สามารถจัดการสิ่งเหล่านั้นได้ หากคุณกำลังตั้งค่า Devise ให้ออกจากระบบผ่าน :delete
และคุณกำลังใช้ลิงก์ (แทนที่จะใช้ปุ่มที่อยู่ในแบบฟอร์ม) เพื่อออกจากระบบด้วย method: :delete
พวกเขาจะต้องได้รับการอัปเดตตามที่อธิบายไว้ข้างต้น (Devise ไม่มีลิงก์/ปุ่มออกจากระบบในมุมมองที่แชร์)
ตรวจสอบให้แน่ใจว่าได้ตรวจสอบมุมมองของคุณเพื่อค้นหาสิ่งเหล่านั้น และเปลี่ยนแปลงอย่างเหมาะสม
Devise ใช้ข้อความแฟลชที่มี I18n ร่วมกับปุ่มแฟลช :notice และ :alert หากต้องการปรับแต่งแอป คุณสามารถตั้งค่าไฟล์ภาษาของคุณได้:
en :
devise :
sessions :
signed_in : ' Signed in successfully. '
คุณยังสามารถสร้างข้อความที่แตกต่างกันตามทรัพยากรที่คุณกำหนดค่าโดยใช้ชื่อเอกพจน์ที่กำหนดในเส้นทาง:
en :
devise :
sessions :
user :
signed_in : ' Welcome user, you are signed in. '
admin :
signed_in : ' Hello admin! '
เมล Devise ใช้รูปแบบที่คล้ายกันเพื่อสร้างข้อความหัวเรื่อง:
en :
devise :
mailer :
confirmation_instructions :
subject : ' Hello everybody! '
user_subject : ' Hello User! Please confirm your email '
reset_password_instructions :
subject : ' Reset instructions '
ดูไฟล์สถานที่ของเราเพื่อตรวจสอบข้อความที่มีอยู่ทั้งหมด คุณอาจสนใจหนึ่งในการแปลจำนวนมากที่มีอยู่ในวิกิของเรา:
https://github.com/heartcombo/devise/wiki/I18n
ข้อควรระวัง: Devise Controllers สืบทอดมาจาก ApplicationController หากแอปของคุณใช้หลายภาษา คุณควรแน่ใจว่าได้ตั้งค่า I18n.locale ใน ApplicationController
Devise มีตัวช่วยทดสอบบางตัวสำหรับการทดสอบคอนโทรลเลอร์และการรวมระบบ หากต้องการใช้งาน คุณจะต้องรวมโมดูลที่เกี่ยวข้องไว้ในกรณีทดสอบ/ข้อกำหนดของคุณ
การทดสอบคอนโทรลเลอร์กำหนดให้คุณรวม Devise::Test::IntegrationHelpers
ในกรณีทดสอบของคุณหรือซูเปอร์คลาส ActionController::TestCase
ระดับบนสุด สำหรับ Rails เวอร์ชันก่อน 5 ให้รวม Devise::Test::ControllerHelpers
แทน เนื่องจากซูเปอร์คลาสสำหรับการทดสอบคอนโทรลเลอร์ถูกเปลี่ยนเป็น ActionDispatch::IntegrationTest (สำหรับรายละเอียดเพิ่มเติม โปรดดูส่วนการทดสอบการรวม)
class PostsControllerTest < ActionController :: TestCase
include Devise :: Test :: IntegrationHelpers # Rails >= 5
end
class PostsControllerTest < ActionController :: TestCase
include Devise :: Test :: ControllerHelpers # Rails < 5
end
หากคุณใช้ RSpec คุณสามารถใส่สิ่งต่อไปนี้ไว้ในไฟล์ชื่อ spec/support/devise.rb
หรือใน spec/spec_helper.rb
ของคุณ (หรือ spec/rails_helper.rb
หากคุณใช้ rspec-rails
):
RSpec . configure do | config |
config . include Devise :: Test :: ControllerHelpers , type : :controller
config . include Devise :: Test :: ControllerHelpers , type : :view
end
เพียงให้แน่ใจว่าการรวมนี้เกิดขึ้น หลังจาก คำสั่ง require 'rspec/rails'
ตอนนี้คุณพร้อมที่จะใช้วิธี sign_in
และ sign_out
ในการทดสอบคอนโทรลเลอร์ของคุณแล้ว:
sign_in @user
sign_in @user , scope : :admin
หากคุณกำลังทดสอบตัวควบคุมภายในของ Devise หรือตัวควบคุมที่สืบทอดมาจากของ Devise คุณต้องบอก Devise ว่าควรใช้การแมปใดก่อนที่จะร้องขอ นี่เป็นสิ่งจำเป็นเนื่องจาก Devise ได้รับข้อมูลนี้จากเราเตอร์ แต่เนื่องจากการทดสอบคอนโทรลเลอร์ไม่ผ่านเราเตอร์ จึงจำเป็นต้องระบุอย่างชัดเจน ตัวอย่างเช่น หากคุณกำลังทดสอบขอบเขตผู้ใช้ เพียงใช้:
test 'GET new' do
# Mimic the router behavior of setting the Devise scope through the env.
@request . env [ 'devise.mapping' ] = Devise . mappings [ :user ]
# Use the sign_in helper to sign in a fixture `User` record.
sign_in users ( :alice )
get :new
# assert something
end
ตัวช่วยทดสอบการรวมพร้อมใช้งานโดยรวมโมดูล Devise::Test::IntegrationHelpers
class PostsTests < ActionDispatch :: IntegrationTest
include Devise :: Test :: IntegrationHelpers
end
ตอนนี้คุณสามารถใช้วิธี sign_in
และ sign_out
ต่อไปนี้ในการทดสอบการรวมของคุณ:
sign_in users ( :bob )
sign_in users ( :bob ) , scope : :admin
sign_out :user
ผู้ใช้ RSpec สามารถรวมโมดูล IntegrationHelpers
ไว้ใน :feature
specs ได้
RSpec . configure do | config |
config . include Devise :: Test :: IntegrationHelpers , type : :feature
end
การทดสอบการรวมไม่จำเป็นต้องระบุค่า env
ของ devise.mapping
ซึ่งแตกต่างจากการทดสอบคอนโทรลเลอร์ เนื่องจากการแมปสามารถอนุมานได้จากเส้นทางที่ดำเนินการในการทดสอบของคุณ
คุณสามารถอ่านเพิ่มเติมเกี่ยวกับการทดสอบคอนโทรลเลอร์ Rails ของคุณด้วย RSpec ได้ในวิกิ:
Devise มาพร้อมกับการสนับสนุน OmniAuth ทันทีเพื่อตรวจสอบสิทธิ์กับผู้ให้บริการรายอื่น หากต้องการใช้งาน เพียงระบุการกำหนดค่า OmniAuth ของคุณใน config/initializers/devise.rb
:
config . omniauth :github , 'APP_ID' , 'APP_SECRET' , scope : 'user,public_repo'
คุณสามารถอ่านเพิ่มเติมเกี่ยวกับการสนับสนุน OmniAuth ได้ในวิกิ:
Devise ช่วยให้คุณสามารถตั้งค่าโมเดล Devise ได้มากเท่าที่คุณต้องการ หากคุณต้องการมีโมเดลผู้ดูแลระบบที่มีเพียงคุณสมบัติการตรวจสอบสิทธิ์และการหมดเวลา นอกเหนือจากโมเดลผู้ใช้ด้านบน เพียงเรียกใช้:
# Create a migration with the required fields
create_table :admins do | t |
t . string :email
t . string :encrypted_password
t . timestamps null : false
end
# Inside your Admin model
devise :database_authenticatable , :timeoutable
# Inside your routes
devise_for :admins
# Inside your protected controller
before_action :authenticate_admin!
# Inside your controllers and views
admin_signed_in?
current_admin
admin_session
หรือคุณสามารถเรียกใช้ตัวสร้าง Devise ได้
โปรดทราบว่าโมเดลเหล่านั้นจะมีเส้นทางที่แตกต่างกันโดยสิ้นเชิง พวกเขา ไม่ได้ใช้ และ ไม่สามารถ ใช้คอนโทรลเลอร์เดียวกันในการลงชื่อเข้าใช้ ออกจากระบบ และอื่นๆ ได้ ในกรณีที่คุณต้องการมีบทบาทที่แตกต่างกันซึ่งใช้การดำเนินการเดียวกัน เราขอแนะนำให้คุณใช้แนวทางตามบทบาท โดยระบุคอลัมน์บทบาทหรือใช้ Gem เฉพาะเพื่อการอนุญาต
หากคุณกำลังใช้งาน Active Job เพื่อส่งข้อความ Action Mailer ในเบื้องหลังผ่านแบ็คเอนด์ที่รอคิว คุณสามารถส่งอีเมล Devise ผ่านคิวที่มีอยู่ได้โดยการแทนที่เมธอด send_devise_notification
ในโมเดลของคุณ
def send_devise_notification ( notification , * args )
devise_mailer . send ( notification , self , * args ) . deliver_later
end
หากคุณเปิดใช้งานโมดูลที่สามารถกู้คืนได้ โปรดทราบว่าโทเค็นการรีเซ็ตรหัสผ่านที่ถูกขโมยอาจทำให้ผู้โจมตีสามารถเข้าถึงแอปพลิเคชันของคุณได้ Devise ใช้ความพยายามในการสร้างโทเค็นแบบสุ่มที่ปลอดภัย และจัดเก็บเฉพาะโทเค็นย่อยในฐานข้อมูล ไม่ใช้ข้อความธรรมดา อย่างไรก็ตามพฤติกรรมการบันทึกเริ่มต้นใน Rails อาจทำให้โทเค็นข้อความธรรมดารั่วไหลเข้าไปในไฟล์บันทึก:
deliver_later
เพื่อส่งอีเมลรีเซ็ตรหัสผ่าน โทเค็นการรีเซ็ตรหัสผ่านจะรั่วไหล Rails ตั้งค่าระดับตัวบันทึกการผลิตเป็น INFO ตามค่าเริ่มต้น ลองเปลี่ยนระดับตัวบันทึกการผลิตของคุณเป็น คำเตือน หากคุณต้องการป้องกันไม่ให้โทเค็นรั่วไหลเข้าไปในบันทึกของคุณ ใน config/environments/production.rb
:
config . log_level = :warn
Devise รองรับ ActiveRecord (ค่าเริ่มต้น) และ Mongoid หากต้องการเลือก ORM อื่น เพียงกำหนดให้อยู่ในไฟล์ตัวเริ่มต้น
Rails 5+ มีโหมด API ในตัวซึ่งปรับ Rails ให้เหมาะสมเพื่อใช้เป็น API (เท่านั้น) Devise ค่อนข้าง สามารถจัดการกับแอปพลิเคชันที่สร้างขึ้นในโหมดนี้ได้โดยไม่ต้องแก้ไขเพิ่มเติมในแง่ที่ว่าไม่ควรเพิ่มข้อยกเว้นและสิ่งที่คล้ายกัน แต่ปัญหาบางอย่างอาจยังคงเกิดขึ้นในระหว่าง development
/ testing
เนื่องจากเรายังไม่ทราบขอบเขตของความเข้ากันได้ทั้งหมด (สำหรับข้อมูลเพิ่มเติม ดูฉบับที่ #4947)
แอปพลิเคชันเฉพาะ API ไม่รองรับการตรวจสอบสิทธิ์ผ่านเบราว์เซอร์ผ่านคุกกี้ ซึ่งเป็นค่าเริ่มต้นของอุปกรณ์ อย่างไรก็ตาม Devise ยังคงสามารถให้การรับรองความถูกต้องได้ทันทีในกรณีเหล่านั้นด้วยกลยุทธ์ http_authenticatable
ซึ่งใช้ HTTP Basic Auth และรับรองความถูกต้องของผู้ใช้ในแต่ละคำขอ (สำหรับข้อมูลเพิ่มเติม โปรดดูบทความวิกินี้สำหรับวิธีการ: ใช้การตรวจสอบสิทธิ์พื้นฐาน HTTP)
ค่าเริ่มต้นของอุปกรณ์สำหรับ HTTP Auth ถูกปิดใช้งาน ดังนั้นจึงจำเป็นต้องเปิดใช้งานในเครื่องมือเริ่มต้นอุปกรณ์สำหรับกลยุทธ์ฐานข้อมูล:
config . http_authenticatable = [ :database ]
ข้อจำกัดนี้ไม่ได้จำกัดคุณจากการใช้กลยุทธ์ Warden แบบกำหนดเอง ไม่ว่าจะในแอปพลิเคชันของคุณหรือผ่านส่วนขยายแบบ Gem สำหรับอุปกรณ์ กลยุทธ์การตรวจสอบสิทธิ์ทั่วไปสำหรับ API คือการตรวจสอบสิทธิ์โดยใช้โทเค็น สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการขยายอุปกรณ์เพื่อรองรับการรับรองความถูกต้องประเภทนี้และอื่นๆ โปรดดูบทความ wiki สำหรับตัวอย่างและทางเลือกการรับรองความถูกต้อง Token อย่างง่าย หรือโพสต์ในบล็อกนี้เกี่ยวกับวิธีการตรวจสอบสิทธิ์แบบกำหนดเองด้วย Devise
โหมด API จะเปลี่ยนลำดับของสแต็กมิดเดิลแวร์ และอาจทำให้เกิดปัญหากับ Devise::Test::IntegrationHelpers
ปัญหานี้มักจะปรากฏเป็น undefined method `[]=' for nil:NilClass
เมื่อใช้ตัวช่วยทดสอบการรวม เช่น #sign_in
วิธีแก้ไขคือเพียงเรียงลำดับมิดเดิลแวร์ใหม่โดยเพิ่มสิ่งต่อไปนี้ใน test.rb:
Rails . application