• SDK
  • OIDC

การพัฒนา SDK ของ OIDC ด้านลูกค้าง่าย ๆ

Logto มี SDK หลากหลายสำหรับแพลตฟอร์มต่าง ๆ นอกเหนือจาก SDK ทางการของเรา เราสนับสนุนนักพัฒนาจากชุมชนให้สร้าง SDK ของตัวเองที่เป็นมิตรกับผู้ใช้ บทความนี้จะนำทางคุณในกระบวนการสร้าง SDK ด้านลูกค้าแบบพื้นฐานสำหรับ OIDC

Simeng
Simeng
Developer

บทนำ

Logto มอบโซลูชั่นการจัดการตัวตนและการเข้าถึงลูกค้าที่ครอบคลุม (CIAM) สำหรับนักพัฒนาและกลุ่มธุรกิจของเรา เรามี SDK ที่พร้อมใช้งานมากมายสำหรับแพลตฟอร์มและเฟรมเวิร์คแอปพลิเคชันที่แตกต่างกัน เมื่อรวมกับบริการคลาวด์ Logto ของเรา คุณสามารถจัดตั้งการไหลของการอนุญาตให้ใช้ที่มีความปลอดภัยสูงให้กับแอปพลิเคชันของคุณได้ภายในไม่กี่นาที ในฐานะบริษัทที่เกิดจากชุมชนนักพัฒนา Logto ยอมรับและเห็นความสำคัญในการมีส่วนร่วมจากชุมชนของเรา นอกเหนือจาก SDK ของ Logto ที่พัฒนาอย่างเป็นทางการแล้ว เรายังคงสนับสนุนและยินดีต้อนรับนักพัฒนาจากชุมชนมาอย่างต่อเนื่องเพื่อมีส่วนร่วมด้วยการสร้าง SDK ที่หลากหลายและเป็นมิตรกับผู้ใช้ เพื่อตอบสนองความต้องการที่เฉพาะเจาะจงของแพลตฟอร์มและเฟรมเวิร์คต่าง ๆ ในบทความนี้ เราจะแสดงวิธีในการดำเนินการ SDK การยืนยันตัวตน OIDC มาตรฐานทีละขั้นตอน

บริบท

การไหลของ OpenID Connect (OIDC) เป็นโปรโตคอลการยืนยันตัวตนที่สร้างขึ้นบนเฟรมเวิร์ค OAuth 2.0 เพื่อให้การตรวจสอบตัวตนและความสามารถในการลงชื่อเข้าครั้งเดียว มันอนุญาตให้ผู้ใช้ยืนยันตัวตนกับแอปพลิเคชันและได้รับการอนุญาตให้เข้าถึงทรัพยากรส่วนตัวใด ๆ อย่างปลอดภัย ดูรายละเอียดเพิ่มเติมได้ที่ข้อกำหนด OIDC

ที่วางแผนงาน

การไหลของการอนุญาตมาตรฐานจะประกอบไปด้วยขั้นตอนดังนี้:

การไหลของการยืนยันตัวตน

  1. ผู้ใช้เริ่มต้นคำขอลงชื่อเข้าใช้: ผู้ใช้ไม่ประสงค์ที่จะเข้ามาที่แอปพลิเคชันของคุณจากทางเข้าทั่วไป พยายามที่จะยืนยันตัวตนและอาจร้องขอเพื่อเข้าถึงทรัพยากรที่ได้รับการป้องกันในแอปพลิเคชันหรือบริการจากบุคคลที่สาม
  2. การยืนยันตัวผู้ใช้: แอปไคลเอนต์สร้าง URI การยืนยันตัวและส่งคำขอไปยังเซิร์ฟเวอร์การอนุญาต ซึ่งนำผู้ใช้ไปยังหน้าลงชื่อเข้าใช้ ผู้ใช้โต้ตอบกับหน้าลงชื่อเข้าใช้โดยใช้วิธีการลงชื่อเข้าใช้ที่หลากหลายและยืนยันตัวตนโดยเซิร์ฟเวอร์การอนุญาต
  3. จัดการการส่งคืนการลงชื่อเข้าใช้: หลังจากการยืนยันตัวตนที่สำเร็จ ผู้ใช้จะถูกเปลี่ยนเส้นทางกลับไปยังแอปพลิเคชันของคุณพร้อมด้วย authorization_code ที่มอบให้ authorization_code นี้ประกอบด้วยการอนุญาตที่เกี่ยวข้องทั้งหมดที่เชื่อมโยงกับสถานะการยืนยันตัวตนและข้อมูลการอนุญาตที่ร้องขอ
  4. การแลกเปลี่ยนโทเคน: ร้องขอการแลกเปลี่ยนโทเคนโดยใช้ authorization_code ที่สกัดจากที่อยู่เปลี่ยนเส้นทางข้างต้น ในการตอบกลับ:
    • id_token: JWT ที่ลงนามดิจิทัลที่มีข้อมูลตัวตนเกี่ยวกับผู้ใช้ที่ยืนยันตัวตนแล้ว
    • access_token: access_token ไม่แน่นอนที่สามารถใช้เข้าถึง endpoint ข้อมูลพื้นฐานของผู้ใช้
    • refresh_token: โทเคนการยืนยันให้ผู้ใช้สามารถแลกเปลี่ยนอย่างต่อเนื่องสำหรับ access_token

การไหลของการอนุญาต

  1. การเข้าถึงข้อมูลผู้ใช้: เพื่อเข้าถึงข้อมูลเพิ่มเติมเกี่ยวกับผู้ใช้ แอปพลิเคชันสามารถส่งคำขอเพิ่มเติมไปยัง endpoint ข้อมูลผู้ใช้ โดยใช้ access_token ไม่แน่นอนที่ได้จากการไหลของการแลกเปลี่ยนโทเคนเริ่มต้น ซึ่งอนุญาตให้การดึงข้อมูลเพิ่มเติมเกี่ยวกับผู้ใช้ เช่น ที่อยู่อีเมลหรือภาพโปรไฟล์ของเขา
  2. การให้การเข้าถึงทรัพยากรที่ได้รับการป้องกัน: หากจำเป็น แอปพลิเคชันสามารถส่งคำขอเพิ่มเติมไปยัง 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

ชื่อคุณสมบัติประเภทจำเป็นรายละเอียดค่าเริ่มต้น
appIdstringtrueตัวระบุแอปพลิเคชันที่ไม่ซ้ำกัน สร้างโดยเซิร์ฟเวอร์การอนุญาตเพื่อระบุแอปพลิเคชันของลูกค้า
appSecretstringความลับของแอปพลิเคชันใช้ร่วมกับ ID ของแอปพลิเคชันเพื่อตรวจสอบตัวตนของผู้ขอ มันจำเป็นสำหรับลูกค้าที่เปิดเผยเช่นเว็บ Go หรือเว็บ Next.js และเสริมสำหรับลูกค้าสาธารณะเช่นแอปพลิเคชันพื้นเมืองหรือแอปแบบหน้าเดี่ยว (SPAs)
endpointstringtrueจุดสิ้นสุดของเซิร์ฟเวอร์การอนุญาตของคุณ คุณสมบัตินี้จะถูกใช้งานอย่างกว้างขวางเพื่อสร้างคำขอการอนุญาต endpoint.
scopesstring listระบุขอบเขตทรัพยากรทั้งหมดที่จำเป็นที่ผู้ใช้อาจจำเป็นต้องได้รับการอนุญาตเพื่อเข้าถึงทรัพยากรที่ปกป้องใด ๆ[reservedScopes]
resourcesstring listตัวชี้วัดของทรัพยากรที่ปกป้องทั้งหมดที่ผู้ใช้อาจร้องขอสำหรับการเข้าถึง

วิธีการช่วย

generateRandomString