การพัฒนา SDK ของ OIDC ด้านลูกค้าง่าย ๆ
Logto มี SDK หลากหลายสำหรับแพลตฟอร์มต่าง ๆ นอกเหนือจาก SDK ทางการของเรา เราสนับสนุนนักพัฒนาจากชุมชนให้สร้าง SDK ของตัวเองที่เป็นมิตรกับผู้ใช้ บทความนี้จะนำทางคุณในกระบวนการสร้าง SDK ด้านลูกค้าแบบพื้นฐานสำหรับ OIDC
บทนำ
Logto มอบโซลูชั่นการจัดการตัวตนและการเข้าถึงลูกค้าที่ครอบคลุม (CIAM) สำหรับนักพัฒนาและกลุ่มธุรกิจของเรา เรามี SDK ที่พร้อมใช้งานมากมายสำหรับแพลตฟอร์มและเฟรมเวิร์คแอปพลิเคชันที่แตกต่างกัน เมื่อรวมกับบริการคลาวด์ Logto ของเรา คุณสามารถจัดตั้งการไหลของการอนุญาตให้ใช้ที่มีความปลอดภัยสูงให้กับแอปพลิเคชันของคุณได้ภายในไม่กี่นาที ในฐานะบริษัทที่เกิดจากชุมชนนักพัฒนา Logto ยอมรับและเห็นความสำคัญในการมีส่วนร่วมจากชุมชนของเรา นอกเหนือจาก SDK ของ Logto ที่พัฒนาอย่างเป็นทางการแล้ว เรายังคงสนับสนุนและยินดีต้อนรับนักพัฒนาจากชุมชนมาอย่างต่อเนื่องเพื่อมีส่วนร่วมด้วยการสร้าง SDK ที่หลากหลายและเป็นมิตรกับผู้ใช้ เพื่อตอบสนองความต้องการที่เฉพาะเจาะจงของแพลตฟอร์มและเฟรมเวิร์คต่าง ๆ ในบทความนี้ เราจะแสดงวิธีในการดำเนินการ SDK การยืนยันตัวตน OIDC มาตรฐานทีละขั้นตอน
บริบท
การไหลของ OpenID Connect (OIDC) เป็นโปรโตคอลการยืนยันตัวตนที่สร้างขึ้นบนเฟรมเวิร์ค OAuth 2.0 เพื่อให้การตรวจสอบตัวตนและความสามารถในการลงชื่อเข้าครั้งเดียว มันอนุญาตให้ผู้ใช้ยืนยันตัวตนกับแอปพลิเคชันและได้รับการอนุญาตให้เข้าถึงทรัพยากรส่วนตัวใด ๆ อย่างปลอดภัย ดูรายละเอียดเพิ่มเติมได้ที่ข้อกำหนด OIDC
ที่วางแผนงาน
การไหลของการอนุญาตมาตรฐานจะประกอบไปด้วยขั้นตอนดังนี้:
การไหลของการยืนยันตัวตน
- ผู้ใช้เริ่มต้นคำขอลงชื่อเข้าใช้: ผู้ใช้ไม่ประสงค์ที่จะเข้ามาที่แอปพลิเคชันของคุณจากทางเข้าทั่วไป พยายามที่จะยืนยันตัวตนและอาจร้องขอเพื่อเข้าถึงทรัพยากรที่ได้รับการป้องกันในแอปพลิเคชันหรือบริการจากบุคคลที่สาม
- การยืนยันตัวผู้ใช้: แอปไคลเอนต์สร้าง URI การยืนยันตัวและส่งคำขอไปยังเซิร์ฟเวอร์การอนุญาต ซึ่งนำผู้ใช้ไปยังหน้าลงชื่อเข้าใช้ ผู้ใช้โต้ตอบกับหน้าลงชื่อเข้าใช้โดยใช้วิธีการลงชื่อเข้าใช้ที่หลากหลายและยืนยันตัวตนโดยเซิร์ฟเวอร์การอนุญาต
- จัดการการส่งคืนการลงชื่อเข้าใช้: หลังจากการยืนยันตัวตนที่สำเร็จ ผู้ใช้จะถูกเปลี่ยนเส้นทางกลับไปยังแอปพลิเคชันของคุณพร้อมด้วย
authorization_code
ที่มอบให้authorization_code
นี้ประกอบด้วยการอนุญาตที่เกี่ยวข้องทั้งหมดที่เชื่อมโยงกับสถานะการยืนยันตัวตนและข้อมูลการอนุญาตที่ร้องขอ - การแลกเปลี่ยนโทเคน: ร้องขอการแลกเปลี่ยนโทเคนโดยใช้
authorization_code
ที่สกัดจากที่อยู่เปลี่ยนเส้นทางข้างต้น ในการตอบกลับ:id_token
: JWT ที่ลงนามดิจิทัลที่มีข้อมูลตัวตนเกี่ยวกับผู้ใช้ที่ยืนยันตัวตนแล้วaccess_token
:access_token
ไม่แน่นอนที่สามารถใช้เข้าถึง endpoint ข้อมูลพื้นฐานของผู้ใช้refresh_token
: โทเคนการยืนยันให้ผู้ใช้สามารถแลกเปลี่ยนอย่างต่อเนื่องสำหรับaccess_token
การไหลของการอนุญาต
- การเข้าถึงข้อมูลผู้ใช้: เพื่อเข้าถึงข้อมูลเพิ่มเติมเกี่ยวกับผู้ใช้ แอปพลิเคชันสามารถส่งคำขอเพิ่มเติมไปยัง endpoint ข้อมูลผู้ใช้ โดยใช้
access_token
ไม่แน่นอนที่ได้จากการไหลของการแลกเปลี่ยนโทเคนเริ่มต้น ซึ่งอนุญาตให้การดึงข้อมูลเพิ่มเติมเกี่ยวกับผู้ใช้ เช่น ที่อยู่อีเมลหรือภาพโปรไฟล์ของเขา - การให้การเข้าถึงทรัพยากรที่ได้รับการป้องกัน: หากจำเป็น แอปพลิเคชันสามารถส่งคำขอเพิ่มเติมไปยัง endpoint การแลกเปลี่ยนโทเคน โดยใช้
refresh_token
รวมกับพารามิเตอร์resource
และscope
เพื่อรับaccess_token
เฉพาะสำหรับผู้ใช้ในการเข้าถึงทรัพยากรเป้าหมาย กระบวนการนี้ส่งผลในการออกaccess_token
รูปแบบ JWT ที่มีข้อมูลการอนุญาตที่จำเป็นทั้งหมดเพื่อเข้าถึงทรัพยากรที่ได้รับการป้องกัน
การดำเนินการ
เราจะปฏิบัติตามกลยุทธ์การออกแบบบางประการภายใน @logto/client JavaScript SDK ของเราเพื่อนำกระบวนการในการสร้าง SDK ง่าย ๆ สำหรับแอปพลิเคชันข้างลูกค้าของคุณเอง โปรดจำไว้ว่าโครงสร้างโค้ดที่ละเอียดอาจแตกต่างกันไปขึ้นอยู่กับเฟรมเวิร์คของลูกค้าคุณที่คุณกำลังทำงานกับ คุณสามารถเลือกใด ๆ ของ SDK ทางการของ Logto เป็นตัวอย่างสำหรับโครงการ SDK ของคุณเอง
การแสดงตัวอย่าง
ตัวสร้าง
ตัวสร้างควรรับ logtoConfig เป็นอินพุตของมัน นี่ให้การกำหนดค่าทั้งหมดที่จำเป็นสำหรับคุณในการสร้างการเชื่อมต่อการยืนยันผ่าน SDK นี้
ขึ้นอยู่กับแพลตฟอร์มหรือเฟรมเวิร์คที่คุณใช้งานสำหรับ SDK คุณอาจส่งตัวอย่างของ storการจัดเก็บข้อมูลท้องถิ่นที่ทนทานให้กับตัวสร้าง ตัวอย่างสตอเรจนี้จะใช้เพื่อเก็บโทเคนและความลับที่เกี่ยวข้องกับการอนุญาตทั้งหมด
การเริ่มต้นการยืนยันตัวตนของผู้ใช้
ก่อนการสร้าง URL การร้องขอการยืนยันตัวตน จำเป็นที่จะต้องดำเนินการตามขั้นตอนการเตรียมการที่จำเป็นหลายขั้นตอนเพื่อให้กระบวนการมีความปลอดภัย
ดึงคอนฟิก OIDC จากเซิร์ฟเวอร์การอนุญาต
กำหนดเมธอดส่วนตัว getOidcConfigs
เพื่อดึงคอนฟิก OIDC จาก endpoint การค้นพบของเซิร์ฟเวอร์การอนุญาต การตอบกลับคอนฟิก OIDC ประกอบด้วยข้อมูลเมทาดาทาทั้งหมดที่ลูกค้าสามารถใช้เพื่อการโต้ตอบกับเซิร์ฟเวอร์การอนุญาต รวมถึงตำแหน่ง endpoint ของมันและความสามารถของเซิร์ฟเวอร์ (โปรดดูที่ OAuth OAuth Authorization Server Metadata Specs สำหรับข้อมูลเพิ่มเติม)
ตัวสร้าง PKCE
การตรวจพิสูจน์ PKCE(Proof Key for Code Exchange) เป็นขั้นตอนสำคัญสำหรับการไหลของรหัสการอนุญาตของลูกค้าสาธารณะทั้งหมด มันลดความเสี่ยงของการโจมตีการจับการเข้ารหัสการอนุญาต ด้วยเหตุนี้ code_challenge
และ code_verifier
เป็นสิ่งจำเป็นสำหรับคำขอการอนุญาตของแอปพลิเคชันของลูกค้าสาธารณะทั้งหมด (เช่น แอปเนทีฟและ SPA)
วิธีการดำเนินการอาจแตกต่างกันไปขึ้นอยู่กับภาษาที่ใช้งานและเฟรมเวิร์คที่คุณกำลังใช้งาน โปรดดูที่ code_challenge และ code_verifier สำหรับการกำหนดรายละเอียด
สร้างพารามิเตอร์ state
ในกระบวนการอนุญาต พารามิเตอร์ state เป็นค่าแบบสุ่มที่สร้างขึ้นซึ่งรวมอยู่ในคำขอการอนุญาตที่ส่งโดยลูกค้า มันทำหน้าที่เป็นมาตรการรักษาความปลอดภัยเพื่อป้องกันการโจมตีปลอมแบบข้ามไซต์ (CSRF)
เก็บข้อมูลเซสชันชั่วคราว
มีหลายพารามิเตอร์ที่ต้องเก็บรักษาในที่จัดเก็บเพื่อวัตถุประสงค์ในการตรวจสอบหลังจากผู้ใช้ได้รับการยืนยันตัวตนและเปลี่ยนเส้นทางกลับไปยังฝั่งลูกค้า เราจะดำเนินการเมธอดในการตั้งค่าพารามิเตอร์ชั่วคราวเหล่านี้ไปยังที่จัดเก็บ
ลงชื่อเข้าใช้
เรามาทบทวนทุกอย่างที่นำมาใช้อยู่ข้างต้นในการกำหนดวิธีการสร้าง URL การลงชื่อเข้าใช้ของผู้ใช้และเปลี่ยนทางผู้ใช้ไปยังเซิร์ฟเวอร์การอนุญาตเพื่อตรวจสอบตัวตน
จัดการการส่งคืนการลงชื่อเข้าใช้ของผู้ใช้
ในส่วนก่อนหน้า เราได้สร้างวิธีการลงชื่อเข้าใช้ที่สร้าง URL สำหรับการยืนยันตัวตนของผู้ใช้ URL นี้ประกอบด้วยพารามิเตอร์ที่จำเป็นทั้งหมดสำหรับการเริ่มการไหลของการยืนยันตัวตนจา กแอปพลิเคชันของลูกค้า วิธีการนี้จะเปลี่ยนทางผู้ใช้ไปยังหน้าลงชื่อเข้าใช้ของเซิร์ฟเวอร์การอนุญาตสำหรับการยืนยันตัวตน หลังจากลงชื่อเข้าใช้ที่สำเร็จ ผู้ใช้จะถูกเปลี่ยนเส้นทางกลับไปยังตำแหน่ง redirect_uri ที่ให้ไว้อยู่แล้ว พารามิเตอร์ที่จำเป็นทั้งหมดจะถูกถือไว้ใน redirect_uri เพื่อดำเนินการการไหลของการแลกเปลี่ยนโทเคนต่อไป
ดึงและตรวจสอบ URL การส่งคืน
ขั้นตอนการตรวจสอบนี้มีความสำคัญอย่างยิ่งที่จะป้องกันรูปแบบใด ๆ ของการโจมตีในการส่งคืนการอนุญาตที่ปลอมแปลง URL การส่งคืน ต้อง ถูกตรวจสอบอย่างรอบคอบก่อนการส่งคำขอแลกเปลี่ยนโทเคนต่อไปยังเซิร์ฟเวอร์การอนุญาต อันดับแรก เราจำเป็นต้องดึงข้อมูลเซสชันการลงชื่อเข้าจากที่เก็บข้อมูลแอปพลิเคชัน
จากนั้น ประเมินความถูกต้องของพารามิเตอร์ URL การส่งคืนก่อนการส่งคำขอแลกเปลี่ยนโทเคนออกไป
- ใช้
redirectUri
ที่เก็บไว้อยู่แล้วเพื่อตรวจสอบว่าcallbackUri
ตรงกับตัวที่เราส่งไปยังเซิร์ฟเวอร์การอนุญาตหรือไม่ - ใช้
state
ที่เก็บไว้อยู่แล้วเพื่อตรวจสอบว่า state ที่ส่งคืนมานั้นตรงกับตัวที่เราส่งไปยังเซิร์ฟเวอร์การอนุญาตหรือไม่ - ตรวจสอบว่ามีข้อผิดพลาดใด ๆ ถูกส่งคืนโดยเซิร์ฟเวอร์การอนุญาตหรือไม่
- ตรวจสอบการมีอยู่ของ
authorization_code
ที่ส่งคืน
ส่งคำขอแลกเปลี่ยนรหัส
เป็นขั้นตอนสุดท้ายของการไหลของการยืนยันตัวผู้ใช้ เราจะใช้ authorization_code
ที่ส่งคืนมาเพื่อส่งคำขอแลกเปลี่ยนโทเคนและรับโทเคนการอนุญาตที่ต้องก าร สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการกำหนดพารามิเตอร์คำขอ โปรดดูที่ ข้อกำหนดการแลกเปลี่ยนโทเคน
- รหัส:
authorization_code
ที่เราได้รับจาก URL การส่งคืน - clientId: รหัสแอปพลิเคชัน
- redirectUri: ค่าเดียวกับที่ใช้เมื่อสร้าง URL การลงชื่อเข้าใช้สำหรับผู้ใช้
- codeVerifier: ตัวสร้าง PKCE code verifier ที่เหมือนกับ redirectUri เซิร์ฟเวอร์การอนุญาตจะเปรียบเทียบค่านี้กับตัวที่เราส่งมาก่อนหน้านี้ เพื่อให้มั่นใจว่าคำขอแลกเปลี่ยนโทเคนที่เข้ามามีการตรวจสอบแล้ว
จัดการการส่งคืนการลงชื่อเข้าใช้
สรุปทุกอย่างที่เรามี มาสร้างเมธอด handleSignInCallback:
ผลลัพธ์ที่ได้คือคำขอแลกเปลี่ยนโทเคนจะส่งคืนโทเคนดังนี้:
id_token
: OIDC idToken, JSON Web Token (JWT) ที่มีข้อมูลตัวตนเกี่ยวกับผู้ใช้ที่ยืนยันตัวตนแล้ว id_token สามารถใช้เป็นหลักฐานแหล่งเดียว (SSOT) ของสถานะการยืนยันตัวตนของผู้ใช้access_token
: โทเคนการอนุญาตมาตรฐานที่ส่งคืนโดยเซิร์ฟเวอร์การอนุญาต สามารถใช้เพื่อเรียกใช้งานและดึงข้อมูลของผู้ใช้ที่ยืนยันตัวตนแล้วrefresh_token
: (ถ้าช่วงการใช้งานออฟไลน์ปรากฏในคำขอการอนุญาต) โทเคนนี้อนุญาตให้แอปพลิเคชันของลูกค้าสามารถรับaccess_token
ใหม่ได้โดยไม่ต้องใช้ผู้ในการยืนยันตัวตนอีกครั้ง เปิดใช้งานการเข้าถึงระยะยาวไปยังทรัพยากรexpires_in
: ระยะเวลาของเวลาในวินาทีที่ @ kwuru ⟩access_token
มีอายุการใช้งานก่อนที่จะหมดอายุ
การตรวจสอบ id_token
การตรวจสอบและการสกัดคำกล่าวจาก id_token
เป็นขั้นตอนสำคัญในกระบวนการยืนยันตัวเพื่อให้แน่ใจในความถูกต้องและความสมบูรณ์ของโทเคน ขึ้นตอนหลักที่เกี่ยวข้องในการตรวจสอบ idToken
- การตรวจสอบลายเซ็น:
id_token
ถูกลายเซ็นดิจิทัลด้วยคีกล่องส่วนตัวเซิร์ฟเวอร์การอนุญาต แอปพลิเคชันของลูกค้าจำเป็นต้องตรวจสอบลายเซ็นโดยใช้คีกลัง fē พφิก เปิดใช้งานให้ติดตามการเปลี่ยนแปลง Wภาพปราณขกดีรูปเปิดการอนุญาตที่ถูกต้อง - การตรวจสอบผู้ออก: ตรวจสอบว่ารายการในคำให้ "iss" (ผู้ออก) ใน
id_token
นั้นตรงกับค่าที่คาดหมายแสดงให้เห็นว่าโทเคนนั้นถูกออกโดยเซิร์ฟเวอร์การอนุญาตที่ถูกต้อง - การตรวจสอบผู้ชม: ตรวจสอบให้แน่ใจว่าคำว่า "aud" (ผู้ชม) ใน
id_token
นั้นตรงกับใลน์สำคัญผู้ใช้ของแอปพลิเคชันของลูกค้า เพื่อให้แน่ใจว่าโทเคนนั้นใช้ติ้งคลายณในเชิงนั้น - การตรวจสอบวันหมดอายุ: ตรวจสอบให้แน่ใจว่าคำว่า "iat" (ออกเมื่อ) ใน
id_token
นั้นยังไม่ผ่านเวลากลางฤทธิ์ เพื่อให้แน่ใจว่าโทเคนนั้นยังมีอายุ ในฐานะมีค่าใช้จ่ายในเครือข่ายที่เกี่ยวข้อง คุณจำเป็นต้องตั้งค่าข้อนขัดในการยืนยันโทเคนจดหมายข้ามในการเข้ารับ
โทเคนที่ส่งคืน id_token นั้นเป็น JSON Web Token มาตรฐาน (JWT) ขึ้นอยู่กับเฟรมเวิร์คที่คุณกำลังใช้ คุณสามารถหา Plugin การตรวจสอบและถอดรหัสการตรวจสอบ JWT สนับสนุนต่างๆ ได้ เพื่อช่วเพจอกในการถอดรหัสและตรวจสอบโทเคน ในตัวอย่างนี้เราจะใช้ jose ใน SDK JavaScript ของเราเพื่ออำนวยความสะดวกในการตรวจสอบและถอดรหัสโทเคน
รับข้อมูลผู้ใช้
หลังจากการยืนยันตัวตนสำเร็จแล้ว ข้อมูลพื้นฐานของผู้ใช้สามารถดึงออกมาจาก id_token
OIDC ได้ที่เซิร์ฟเวอร์การอนุ ญาต อย่างไรก็ตาม เนื่องจากข้อควรพิจารณาเรื่องประสิทธิภาพ เนื้อหาภายใน JWT จำกัด ในการขอรับข้อมูลโปรไฟล์ผู้ใช้เพิ่มเติม เซิร์ฟเวอร์การอนุญาตที่สอดคล้องกับ OIDC มี Endpoint ข้อมูลผู้ใช้แบบ out-of-the-box ที่อนุญาตให้คุณขอข้อมูลโปรไฟล์ผู้ใช้เพิ่มเติมตามขอบเขตการโปรไฟล์ที่ระบุ
เมื่อเรียกติดต่อลิขสิทธิ์การแลกเปลี่ยน โดยไม่ระบุตัวบอกทรัพยากรเฉพาะ เซิร์ฟเวอร์การอนุญาตจะออก access_token
ประเภทไม่แน่นอนตามกำหนด เรียกขอข้อมูลโปรไฟล์พื้นฐานของผู้ใช้
รับโทเคนการเข้าถึงสำหรับการอนุญาตทรัพยากรที่ได้รับการคุ้มครอง
ในหลายกรณี แอปพลิเคชันของลูกค้าต้องการไม่เ พียงแค่การยืนยันตัวตนของผู้ใช้ แต่ยังต้องการการอนุญาตของผู้ใช้เพื่อเข้าถึงทรัพยากรบางอย่างหรือ Endpoint ของ API ที่ได้รับการคุ้มครอง ที่นี่เราจะใช้ refresh_token
ที่ได้รับระหว่างการเข้าสู่ระบบเพื่อรับ access_token(s)
ที่มอบให้เฉพาะสำหรับจัดการทรัพยากรบางอย่าง ซึ่งช่วยให้เราได้รับการเข้าถึง API ที่ได้รับการคุ้มครองนั้น
สรุป
เราได้ให้การดำเนินการเมธอดที่สำคัญสำหรับกระบวนการยืนยันตัวตนและการอนุญาตของแอปพลิเคชันข้างลูกค้า ขึ้นอยู่กับสถานการณ์ที่เฉพาะเจาะจงของคุณ คุณสามารถจัดระเบียบและปรับปรุงตรรกะ SDK ตามที่จำเป็น โปรดทราบว่าอาจมีความแตกต่างอันเกิดจากแพลตฟอร์มและเฟรมเวิร์คที่แตกต่างกัน
สำหรับรายละเอียดเพิ่มเติม ค้นหาแพ็คเกจ SDK ที่เสนอโดน Logto เรายินดีรับความรู้อันมีค่าจากเพื่อนนักพัฒนาทุกคนเพื่อเข้ามามีส่วนร่วมและพูดคุยกับเรา ฟีดแบ็กและความมีส่วนร่วมของคุณมีค่าอย่างยิ่งในขณะที่เรายังคงปรับปรุงและขยายความสามารถของ SDK
ภาคผนวก
ขอบเข ตที่สงวนไว้
Logto ขอบเขตที่คุณจำเป็นต้องส่งผ่านในระหว่างการขออนุญาตเบื้องต้น ขอบเขตเหล่านี้อาจเป็น OIDC ที่สงวนไว้หรือ Logto ที่สงวนไว้ซึ่งเป็นขอบเขตพื้นฐานสำหรับการให้สิทธิ์การอนุญาตแบบสำเร็จรูป
ชื่อขอบเขต | รายละเอียด |
---|---|
openid | จำเป็นสำหรับการมอบ id_token หลังการยืนยันตัวตนที่สำเร็จ |
offline-access | จำเป็นสำหรับการมอบ refresh_token ที่อนุญาตให้แอปพลิเคชันของคุณสลับและต่ออายุ access_token นอกเหนือจากหน้าจอ |
โปรไฟล์ | จำเป็นสำหรับการเข้าถึงข้อมูลพื้นฐานของผู้ใช้ |
การกำหนดค่า Logto
ชื่อคุณสมบัติ | ประเภท | จำเป็น | รายละเอียด | ค่าเริ่มต้น |
---|---|---|---|---|
appId | string | true | ตัวระบุแอปพลิเคชันที่ไม่ซ้ำกัน สร้างโดยเซิร์ฟเวอร์การอนุญาตเพื่อระบุแอปพลิเคชันของลูกค้า | |
appSecret | string | ความลับของแอปพลิเคชันใช้ร่วมกับ ID ของแอปพลิเคชันเพื่อตรวจสอบตัวตนของผู้ขอ มันจำเป็นสำหรับลูกค้าที่เปิดเผยเช่นเว็บ Go หรือเว็บ Next.js และเสริมสำหรับลูกค้าสาธารณะเช่นแอปพลิเคชันพื้นเมืองหรือแอปแบบหน้าเดี่ยว (SPAs) | ||
endpoint | string | true | จุดสิ้นสุดของเซิร์ฟเวอร์การอนุญาตของคุณ คุณสมบัตินี้จะถูกใช้งานอย่างกว้างขวางเพื่อสร้างคำขอการอนุญาต endpoint. | |
scopes | string list | ระบุขอบเขตทรัพยากรทั้งหมดที่จำเป็นที่ผู้ใช้อาจจำเป็นต้องได้รับการอนุญาตเพื่อเข้าถึงทรัพยากรที่ปกป้องใด ๆ | [reservedScopes] | |
resources | string list | ตัวชี้วัดของทรัพยากรที่ปกป้องทั้งหมดที่ผู้ใช้อาจร้องขอสำหรับการเข้าถึง |