เพิ่ม Sign in บน Rails ด้วย Devise

เสก Rails ให้ใช้งานได้จริง 002

Shumnan Sun
Ascend Developers

--

Devise เป็น gem ตัวหนึ่งของ Ruby เมื่อลงในแอป จะทำให้ Rails มีระบบสำหรับยืนยันตัวตนผู้ใช้งานเช่น Login, Logout รวมทั้งฟังก์ชั่นที่เกี่ยวกับ account เช่น ส่งเมลยืนยัน Authentication อื่นๆ รวมทั้งหน้าจอให้ในทันทีหลังจากลงใน Rails เสร็จ

บทความนี้นำใช้โค้ดต่อเนื่องมาจาก เพิ่ม Navigation bar ให้ Railsโดยใช้ Partial Page มาเขียนต่อได้เลย โดยให้เลือก clone จาก commit ที่คอมเมนต์ไว้ว่า 001_navigator_bar

1) ติดตั้ง Devise Gem

  • เปิด Gem repo เพื่อหา Devise gem เวอร์ชั่นล่าสุด
  • เปิดไฟล์ Gemfile แล้วเพิ่ม Gem ตัวใหม่ลงไป
    (เนื่องจากเราใช้ ทุก Environment จึงต้องไว้นอก group)
gem 'devise', '~> 4.8'
  • รันคำสั่ง Install ผ่าน bundle เพื่อติดตั้ง Gem เพิ่ม
bundle install
หลัง bundle install

2) ติดตั้ง Devise เพิ่มเติม

หลัง Install Gem บางตัวต้องมีการติดตั้งเพิ่มเติม Devise ก็เป็น Gem ที่ต้องติดตั้งเพิ่มเติมเช่นกัน โดยมีขั้นตอนดังนี้

  • เพิ่มคอนฟิก และสร้างไฟล์คอนฟิกสำหรับ Devise
rails generate devise:install
หลัง devise:install
  • เปิดไฟล์ config/environments/development.rb แล้วเพิ่มคอนฟิกด้านล่าง
    (หาก Deploy บน production เราจะต้องไปคอนฟิกเพิ่มบน production.rb ด้วย)
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
  • เช็คว่าไฟล์ config/routes.rb มีตั้งค่า home
root 'home#index', :as => :home
  • เปิดไฟล์ app/views/layouts/application.html.erb แล้วเพิ่มโค้ด
    โค้ดเหล่านี้ใช้ แสดง Flash Message จาก Rails และ Devise
    เช่น Password ผิดเป็นต้น
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
  • เปิดไฟล์ config/initializers/devise.rb เพื่อแก้คอนฟิกให้ใช้ GET แทน DELETE
# config.sign_out_via = :delete
config.sign_out_via = :get
  • รันโค้ดด้านล่าง เพื่อสร้าง View สำหรับ Devise
    เช่นหน้าจอ Register, Signin และ ChangePassword เป็นต้น
rails g devise:views

3) Migrate ฟิลด์สำหรับ Devise

  • รันโค้ดด้านล่าง สร้าง Migration Script สำหรับ Devise
rails g devise user
  • รันโค้ดด้านล่าง เพื่อเพิ่มฟิลด์สำหรับ Devise
rails db:migrate
  • ตรวจสอบหน้าจอที่สร้างเพิ่มโดยจาก Devise โดยรันคำสั่ง
rails routes|grep devise
  • เปิด URL: http://localhost:3000/users/sign_in
    หน้าจอจะแสดงฟิลด์สำหรับระบุ username และ password
    (ได้มาจาก route ชื่อ new_user_session)

4) แสดงข้อมูลบางส่วน สำหรับ User ที่ Sign in แล้ว

หลังจากสร้างหน้าจอ และคอนฟิกต่างๆ ของ Devise ครบแล้ว ก็ต้องนำสิ่งเหล่านี้ไปใช้กับแอปเราเพื่อแสดงข้อมูลบางส่วนสำหรับ User ที่ Sign in เข้าในระบบแล้วเท่านั้น

  • เปิดไฟล์ app/views/shared/_header.html.erb และเพิ่มโค้ด
    ให้แสดงปุ่ม Sign out และ Edit user เมื่อ Sign in เข้ามาในระบบแล้วเท่านั้น
    โดยใช้ embedded Ruby หรือ eRuby
<!-- Embedded ruby เพื่อตรวจสอบและแสดงโค้ดส่วนนี้เมื่อ Sign in แล้วเท่านั้น -->
<% if user_signed_in? %>
<li class="nav-item">
<!-- ลิงค์ไปหน้า Sign out -->
<%= link_to "Sign Out", destroy_user_session_path, class: "nav-link" %>
</li>
<li class="nav-item">
<!-- ลิงค์ไปหน้า Edit user -->
<%= link_to "Sign Out", edit_user_session_path, class: "nav-link" %>
</li>
<!-- Embedded ruby จะแสดงโค้ดส่วนนี้หากยังไม่ได้ Sign in-->
<% else %>
<li class="nav-item">
<!-- ลิงค์ไปหน้า Sign up -->
<%= link_to "Sign Up", new_user_registration_path, class: "nav-link" %>
</li>
<li class="nav-item">
<!-- ลิงค์ไปหน้า Sign in -->
<%= link_to "Sign In", new_user_session_path, class: "nav-link" %>
</li>
<% end %>
  • จากไฟล์ app/views/shared/_header.html.erb
    แก้ไข Home และ About ให้ลิงค์ที่ถูกต้องโดยการสร้างผ่าน Helper โดย eRuby
<li class="nav-item">
<!-- ใช้ Helper เพื่อสร้างลิงค์ Home แทน static path -->
<%= link_to "Home", home_path, class: "nav-link" %>
</li>
...
<li class="nav-item">
<!-- ใช้ Helper เพื่อสร้างลิงค์ About แทน static path -->
<%= link_to "About", about_path, class: "nav-link" %>
</li>
  • รันคำสั่ง rails s อีกครั้ง
หน้า Home ก่อน Sign in
หน้า About หลัง Sign in

สรุป

Rails สามารถเพิ่มระบบที่เกี่ยวกับ User Authentication ได้ทันทีโดยใช้เพียงแค่ติดตั้ง Gem ชื่อ Devise จากนั้นนำคำสั่งมาใส่ในหน้าต่างที่ Rails หรือ Devise สร้างขึ้นมาเพื่อให้ทำตามเงื่อนไข เช่น ต้อง Sign in ก่อน ถึงจะแสดงหน้าจอส่วนนั้นได้โดยใช้ eRuby

--

--

Develop Test and Deploy. Interesting in develop pipeline. Still young in information analysis and A.I.