Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

เชี่ยวชาญ Action Policy ใน Ruby on Rails: คู่มือปฏิบัติจริงสำหรับ Authorization ที่ปลอดภัย

เพื่อให้แอปของคุณปลอดภัย คุณต้องควบคุมว่าใครและอะไรสามารถเข้าถึงได้ Access control สามารถจัดหมวดหมู่ได้เป็น authentication — "ใคร" ที่จะอนุญาต — และ authorization — "อะไร" ที่พวกเขาสามารถเข้าถึงได้

Authentication เป็นเรื่องสำหรับวันอื่น แตเมื่อพูดถึง user authorization คุณโดยทั่วไปมีสองวิธี: ใช้ role-based หรือ resource-based strategy

ใน series สองส่วนนี้ เราจะ deep dive ใส่การใช้ Action Policy gem สำหรับ Ruby on Rails blog application

ในส่วนนี้ เราจะครอบคลุม basics ของ Action Policy

มาเริ่มกัน!

Prerequisites (ข้อกำหนดเบื้องต้น)

  • Ruby (เราใช้ version 3.2.2)
  • Rails (ใช้ version 7.0.7)
  • ประสบการณ์บางอย่างในการใช้ Ruby

มาเจาะลึกโดยการ define resource-based authorization ก่อน

Resource-Based Authorization คืออะไร?

ในขณะที่ role-based authorization เน้นการตั้งค่า user permissions ตาม predefined user roles resource-based authorization บังคับการเข้าถึงโดยการตั้งกฎบน actual resources ภายในแอปพลิเคชัน แต่ละ resource เชื่อมโยงกับ policy ที่ define อย่างชัดเจนว่าผู้ใช้สามารถทำอะไรบน resource นั้นได้บ้าง

แม้บทความนี้จะเน้น resource-based authorization การรู้ความแตกต่างระหว่างสอง authorization strategies หมายความว่าคุณมีอุปกรณ์ที่ดีกว่าในการรู้ว่าแต่ละอันทำอะไรได้บ้าง

เมื่อไหร่ควรใช้ Role-Based Authorization

คุณควรใช้ role-based authorization สำหรับ:

  • Simple applications - หากคุณทำงานบนแอปที่มี permissions system straightfoward และ fewer user roles role-based authorization strategy อาจทำงานได้สำหรับคุณ
  • Well-defined user groups - หากแอปของคุณมี well-defined user groups เช่น "admins", "editors", "writers" และอื่นๆ ใช้ role-based authorization เพราะมันจัดการ access control ที่ user role level

เมื่อไหร่ควรใช้ Resource-Based Authorization

Resource-based authorization ยอดเยี่ยมสำหรับ:

  • Dynamic หรือ complex access control - เมื่อ authorization needs ของแอปพลิเคชันของคุณ evolve บ่อย หรือถูกกำหนดโดย dynamic conditions resource-based authorization system ทำให้เป็นตัวเลือกที่ดีกว่า
  • Fine-grained control (การควบคุมละเอียด) - เหมาะสำหรับเมื่อคุณต้องอนุญาตหรือปฏิเสธการเข้าถึง resources ตาม multiple conditions (ตัวอย่างเช่น Rails helpdesk app ที่ผู้ใช้ submit support tickets ตาม dynamic categories list) สมมติ support staff ถูก assign tickets โดย category นี่คือ scenario ที่ resource-based authorization จะ shine จริงๆ
  • Object-oriented control (การควบคุมแบบ object-oriented) - เนื่องจาก resource-based authorization เกิดขึ้นที่ object level การกำหนด complex object-oriented rules จะง่ายกว่าเมื่อคุณใช้ resource-based authorization techniques

ถึงอย่างไรก็ตาม ไม่ว่าคุณจะเลือก role-based หรือ resource-based authorization จะขึ้นอยู่กับ unique characteristics ของแอปพลิเคชันของคุณ

มาเปลี่ยนไปเน้นที่ Action Policy gem

Action Policy Gem สำหรับ Ruby และ Rails

Action Policy เป็น authorization framework ที่ flexible, extensible และ performant สำหรับ Ruby และ Rails apps มันใช้ multiple caching strategies out of the box ทำให้มันเร็วมาก โดยเฉพาะถ้า authorization rules ของคุณต้องการ database queries

คุณสมบัติอีกอย่างที่ทำให้ gem นี้ ideal สำหรับการสร้าง resource-based rules คือความสามารถในการปรับแต่ง มันให้ several Ruby classes และ modules ที่สามารถ combine ได้หลายวิธี คุณสามารถตั้งค่า fine-grained access control rules ไปได้เกือบที่ไหนในแอปของคุณ ไปไหนก็ได้เกินกว่า Rails controller

ดู Action Policy project homepage เพื่อเรียนรู้เพิ่มเติม

ตอนนี้มาไปดู Rails app ที่เราจะสร้างวันนี้

สร้าง Rails App

มoving forward เราจะ reference Rails 7 blog application ที่ users สามารถ Create, Read, Update, และ Delete (CRUD) posts

เราจะ progressively define action policy สำหรับ Post model ที่เสนอ resource-based access control คุณจะเรียนรู้วิธีใช้ Action Policy ให้ access control strategy นี้ทำงาน

ไปข้างหน้าและ generate new Rails application:


Note: เราจะใช้ Pico CSS styles สำหรับ example app ของเรา แตคุณสามารถใช้สิ่งที่คุณชอบได้

จากนั้น scaffold Post resource อย่างรวดเร็วที่เราจะใช้ตลอด tutorial:


ตอนนี้รัน migration ด้วย rails db:migrate

การตั้งค่า User Authentication

มากกว่านี้บทความนี้เกี่ยวกับ user authorization มีสิ่งสำคัญที่เราต้องครอบคลุม: user authentication โดยไม่มีมัน authorization policies ใดๆ ที่เราพยายาม define ภายหลังจะไร้ประโยชน์ แตไม่จำเป็นต้องเขียน authentication จากศูนย์ มาใช้ Devise

การติดตั้ง Devise

เริ่มต้นด้วยการเพิ่ม Devise gem ลงใน Gemfile:


จากนั้นติดตั้งและ generate User model:


อย่าลืมเพิ่ม config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } ลงใน development configuration ของแอป

ต่อไป มา implement basic user roles ไปสักหน่อยเพื่อทดสอบ user access scenarios ต่างๆ สำหรับ Post resource

การกำหนด Basic User Roles

ก่อนอื่น เพิ่มคอลัมน์ role ไปที่ user table รันคำสั่งนี้เพื่อ generate migration:


Note: เราใช้ integer data type สำหรับ role เพื่อให้เราสามารถใช้ enum — วิธีเร็วและง่ายในการ implement roles

ตอนนี้รัน migration ด้วย rails db:migrate แล้วเปิด User model ขึ้นมาและแก้ไข:


เมื่อทำเสร็จ มาเปลี่ยนฟอกัสไปที่การติดตั้ง Action Policy

การตั้งค่า Action Policy สำหรับ Ruby และ Rails

เปิด Gemfile ของแอปและเพิ่มบรรทัดด้านล่าง:


จากนั้นรันคำสั่ง bundle install เพื่อติดตั้ง Action Policy

เสร็จสิ้นการติดตั้งโดยการรัน:


สิ่งนี้ควรให้เรา base — ApplicationPolicy class ภายใต้ app/policies:


การใช้งาน Action Policy แบบพื้นฐาน

Core foundation ของ Action Policy คือ policy class, ApplicationPolicy ที่คุณสามารถกำหนด global configurations ที่ policies ทั้งหมดสามารถสืบทอดได้ คำแนะนำที่ดีคือวาง policies ทั้งหมดภายใต้ app/policies และแยก policies ตาม resources ในแอปของคุณ ตัวอย่างเช่น หากคุณมี Post resource policy ที่ตรงกันควรเป็น PostPolicy, CommentPolicy จะไปกับ Comment resource และต่อไป

อีกอย่างหนึ่งที่ต้องพิจารณาเมื่อทำงานกับ Action Policy: rule definitions ต้องเกิดขึ้นภายใน public methods ใน policy classes การใช้ private method จะ raise error

มoving on มาใช้ข้อมูลนี้สร้าง PostPolicy ที่เราจะ progressively build various levels ของ user access

การสร้าง Policy แรกของเรา

สร้างไฟล์ใหม่ชื่อ post_policy.rb ภายใต้ app/policies:


ที่นี่ เรากำหนดกฎง่ายๆ บน Post resource ประกาศว่าใครก็ตามสามารถเข้าถึง Post ได้

การเชื่อมโยง Posts กับ Users

เพื่อทำงานกับ post policy ใหม่นี้ เราต้องปรับ Post resource ที่เรา generate ไว้ก่อนหน้านี้ ให้มัน associated กับ logged-in user เมื่อสร้าง (โดยเพิ่มคอลัมน์ user_id ไปที่ posts table):


จากนั้นรัน migration ด้วย rails db:migrate

ต่อไป เราต้องปรับ posts controller ให้คำนึงถึงการเปลี่ยนแปลงนี้ ก่อนอื่น ให้เพิ่ม user_id ไปที่ allowed post_params:


จากนั้นปรับ create action:


ต่อไป มา secure PostsController

การ Implement Authorization ใน Controllers

เราต้องปรับ PostsController ด้วย callback เพื่ออนุญาตให้ logged-in users เท่านั้น:


ต่อไป มาใช้ Post policy ใหม่เพื่อเพิ่ม basic user access controls บางอย่าง:


ที่นี่ เรากำหนด access rule บน update และ destroy actions ของ posts controller เราระบุว่า author ของ post (หรือ user ที่มี role "author") สามารถ update post ได้ แตเพียง author ของ post เท่านั้นที่สามารถ delete post ได้

Quick tip: Action Policy สามารถอ้างอิง current_user ที่ Devise 提供 และ assign ให้กับ user ภายใน policy

ต่อไป เราต้องใช้ access rule ใน posts controller แบบนี้:


ด้วย access rule ที่ applied ไปที่ posts controller แล้ว ขั้นตอนต่อไปคือให้แน่ใจว่า views ได้รับการป้องกัน

การป้องกัน Views ด้วย Authorization

ในสกรีนชอตด้านล่าง user ที่มี email <user2@example.com> และ role "reader" กำลัง logged in ตามที่เห็น user นี้สามารถ view post ที่สร้างโดย <user@example.com> และพวกเขายังมี access ไปยัง edit และ delete links สำหรับ post นี้ นี่ไม่ ideal — edit และ delete links ควรพร้อมใช้งานสำหรับ author ของ post เท่านั้น

เชี่ยวชาญ Action Policy ใน Ruby on Rails: คู่มือปฏิบัติจริงสำหรับ Authorization ที่ปลอดภัย

ภารกิจแรกของเราจะเป็นการลบ access ไปยัง links เหล่านี้สำหรับ users ที่ไม่ใช่ authors ของ post เนื่องจากเราได้ define access rule นี้แล้ว เราแค่ต้อง apply มันไปที่ show view โดยใช้ allowed_to? method นifty ของ Action Policy:


ด้วย rule ที่ applied แล้ว เราสามารถ refresh หน้า show ของ post และดูสิ่งที่เราได้:

เชี่ยวชาญ Action Policy ใน Ruby on Rails: คู่มือปฏิบัติจริงสำหรับ Authorization ที่ปลอดภัย

User เดียวกันที่เคยมี access ตอนนี้ถูกจำกัดสิ่งที่พวกเขาทำได้ขณะอยู่บน view ของ post

สรุป

ในส่วนแรกของ series สองส่วนนี้ เราได้เรียนรู้ basics บางอย่างรอบๆ authorization gem Action Policy

ในส่วนที่สองและส่วนสุดท้าย เราจะสำรวจ more advanced use cases

Happy coding!

P.S. หากคุณต้องการอ่านโพสต์ Ruby Magic ทันทีที่เผยแพร่ ให้สมัครสมาชิก newsletter Ruby Magic ของเรา และจะไม่พลาดโพสต์เด็ดๆ ไป!