โฟลว์โทเค็นการรีเฟรช JWT


129

ฉันกำลังสร้างแอพมือถือและกำลังใช้ JWT สำหรับการพิสูจน์ตัวตน

ดูเหมือนว่าวิธีที่ดีที่สุดในการทำเช่นนี้คือการจับคู่โทเค็นการเข้าถึง JWT กับโทเค็นการรีเฟรชเพื่อให้ฉันสามารถหมดอายุโทเค็นการเข้าถึงได้บ่อยเท่าที่ฉันต้องการ

  1. โทเค็นการรีเฟรชมีลักษณะอย่างไร มันเป็นสตริงสุ่มหรือไม่? สตริงนั้นเข้ารหัสหรือไม่ เป็น JWT อื่นหรือไม่?
  2. โทเค็นการรีเฟรชจะถูกเก็บไว้ในฐานข้อมูลบนโมเดลผู้ใช้สำหรับการเข้าถึงถูกต้องหรือไม่? ดูเหมือนว่าควรเข้ารหัสในกรณีนี้
  3. ฉันจะส่งโทเค็นการรีเฟรชกลับหลังจากล็อกอินของผู้ใช้แล้วให้ไคลเอนต์เข้าถึงเส้นทางแยกต่างหากเพื่อดึงโทเค็นการเข้าถึงหรือไม่

3
หมายเหตุหากคุณใช้โทเค็นการรีเฟรชคุณควรให้ความสามารถสำหรับผู้ใช้ในการทำให้ไม่ถูกต้องบน UI ขอแนะนำให้หมดอายุโดยอัตโนมัติหากไม่ได้ใช้งานเป็นเวลาหนึ่งเดือน
Vilmantas Baranauskas

1
@jtmarmon: คุณจะจัดเก็บโทเค็นการรีเฟรชในฝั่งไคลเอ็นต์ได้อย่างไร? ฉันหมายถึงอุปกรณ์ Android ที่มีความปลอดภัย?
j10

คำตอบ:


39

สมมติว่านี่เป็นเรื่องเกี่ยวกับ OAuth 2.0 เนื่องจากเป็นเรื่องเกี่ยวกับ JWT และการรีเฟรชโทเค็น ... :

  1. เช่นเดียวกับโทเค็นการเข้าถึงโดยหลักการแล้วโทเค็นการรีเฟรชอาจเป็นอะไรก็ได้รวมถึงตัวเลือกทั้งหมดที่คุณอธิบาย สามารถใช้ JWT เมื่อเซิร์ฟเวอร์การอนุญาตต้องการเป็นคนไร้สัญชาติหรือต้องการบังคับใช้ความหมาย "พิสูจน์การครอบครอง" บางประเภทกับไคลเอ็นต์ที่นำเสนอ โปรดทราบว่าโทเค็นการรีเฟรชแตกต่างจากโทเค็นการเข้าถึงตรงที่ไม่ได้แสดงให้กับเซิร์ฟเวอร์ทรัพยากร แต่เฉพาะกับเซิร์ฟเวอร์การอนุญาตที่ออกให้ตั้งแต่แรกดังนั้นการเพิ่มประสิทธิภาพการตรวจสอบความถูกต้องในตัวเองสำหรับ JWTs-as-access-tokens ไม่ถือเพื่อรีเฟรชโทเค็น

  2. ขึ้นอยู่กับความปลอดภัย / การเข้าถึงฐานข้อมูล หากบุคคลอื่น / เซิร์ฟเวอร์ / แอปพลิเคชัน / ผู้ใช้สามารถเข้าถึงฐานข้อมูลได้ใช่ (แต่ระยะทางของคุณอาจแตกต่างกันไปตามสถานที่และวิธีการจัดเก็บคีย์เข้ารหัส ... )

  3. เซิร์ฟเวอร์การอนุญาตอาจออกทั้งโทเค็นการเข้าถึงและโทเค็นการรีเฟรชในเวลาเดียวกันขึ้นอยู่กับการให้สิทธิ์ที่ไคลเอ็นต์ใช้เพื่อรับ ข้อมูลจำเพาะประกอบด้วยรายละเอียดและตัวเลือกของทุนมาตรฐานแต่ละรายการ


31
2. คุณควรเก็บแฮชของโทเค็นการรีเฟรชไว้ในฐานข้อมูลของคุณจากนั้นเปรียบเทียบแฮชของโทเค็นการรีเฟรชของผู้ใช้กับแฮชที่เก็บไว้ของคุณ กฎของ "อย่าเก็บรหัสผ่านข้อความธรรมดาในฐานข้อมูลของคุณ" มีดังนี้ พิจารณาโทเค็นเหมือนรหัสผ่านแบบสุ่มที่คุณสร้างขึ้นสำหรับผู้ใช้
Rohmer

2
นอกจากนี้หากคุณต้องการเพิ่มความปลอดภัยให้ทำการรีเฟรชโทเค็นด้วย ความสำคัญของการนี้เป็นที่กล่าวถึงแล้วในITEF RFC 6749 หากนำไปใช้อย่างถูกต้องสิ่งนี้ยังสามารถช่วยในการระบุสถานการณ์การโจรกรรมโทเค็นกล่าวคือโทเค็นการรีเฟรชถูกขโมยโดยผู้โจมตี หากคุณกำลังมองหาคำอธิบายที่ดีกว่าให้ไปที่ลิงค์
ภูมิสราไวยา

84

ด้านล่างนี้เป็นขั้นตอนในการเพิกถอนโทเค็นการเข้าถึง JWT ของคุณ:

  1. เมื่อคุณเข้าสู่ระบบให้ส่ง 2 โทเค็น (โทเค็นการเข้าถึง, รีเฟรชโทเค็น) เพื่อตอบสนองกับไคลเอนต์
  2. โทเค็นการเข้าถึงจะมีเวลาหมดอายุน้อยลงและการรีเฟรชจะมีเวลาหมดอายุที่ยาวนาน
  3. ไคลเอนต์ (ส่วนหน้า) จะจัดเก็บโทเค็นการรีเฟรชในที่จัดเก็บในตัวเครื่องและโทเค็นการเข้าถึงในคุกกี้
  4. ไคลเอนต์จะใช้โทเค็นการเข้าถึงเพื่อเรียก API แต่เมื่อหมดอายุให้เลือกโทเค็นการรีเฟรชจากที่จัดเก็บในตัวเครื่องและเรียกใช้ auth server API เพื่อรับโทเค็นใหม่
  5. เซิร์ฟเวอร์รับรองความถูกต้องของคุณจะมี API ที่เปิดเผยซึ่งจะยอมรับโทเค็นการรีเฟรชและตรวจสอบความถูกต้องและส่งคืนโทเค็นการเข้าถึงใหม่
  6. เมื่อโทเค็นการรีเฟรชหมดอายุผู้ใช้จะออกจากระบบ

โปรดแจ้งให้เราทราบหากคุณต้องการรายละเอียดเพิ่มเติมฉันสามารถแบ่งปันรหัส (Java + Spring boot) ได้เช่นกัน

สำหรับคำถามของคุณ:

Q1: เป็นอีกหนึ่ง JWT ที่มีการอ้างสิทธิ์น้อยลงและมีเวลาหมดอายุที่ยาวนาน

Q2: จะไม่อยู่ในฐานข้อมูล แบ็กเอนด์จะไม่จัดเก็บที่ใดก็ได้ พวกเขาจะถอดรหัสโทเค็นด้วยคีย์ส่วนตัว / สาธารณะและตรวจสอบความถูกต้องด้วยเวลาหมดอายุด้วย

Q3: ใช่ถูกต้อง


28
ฉันคิดว่าควรเก็บ JWT ไว้ในlocalStorageและrefreshTokenควรเก็บไว้ในไฟล์httpOnly. refreshToeknสามารถนำมาใช้เพื่อให้ได้ JWT ใหม่ดังนั้นจึงจะต้องมีการจัดการด้วยความระมัดระวังเป็นพิเศษ
Tnc Andrei

2
ขอบคุณคุณหมายถึงอะไรโดยการจัดเก็บใน httpOnly? ทำไมไม่เก็บทั้งสองอย่างใน localStorage
Jay

8
ฉันไม่ได้รับประโยชน์จากการใช้โทเค็นการรีเฟรชจะไม่เหมือนกับการขยายความถูกต้องของโทเค็นการเข้าถึงหรือไม่
user2010955

3
@Jay ตามเครือข่ายนักพัฒนาของ Microsoft HttpOnly เป็นแฟล็กเพิ่มเติมที่รวมอยู่ในส่วนหัวการตอบสนอง HTTP ของ Set-Cookie การใช้แฟล็ก HttpOnly เมื่อสร้างคุกกี้ช่วยลดความเสี่ยงที่สคริปต์ฝั่งไคลเอ็นต์จะเข้าถึงคุกกี้ที่มีการป้องกัน (หากเบราว์เซอร์รองรับ)
shadow0359

23
# 2 มีความไม่ถูกต้องมาก โทเค็นการรีเฟรช HAS จะถูกเก็บไว้ที่ฝั่งเซิร์ฟเวอร์ คุณไม่ควรใช้คุณสมบัติ "ในตัว" ของ JWT สำหรับโทเค็นการรีเฟรช การทำเช่นนี้จะทำให้คุณไม่สามารถเพิกถอนโทเค็นการรีเฟรชได้นอกจากเปลี่ยนคีย์ส่วนตัวของคุณ
Jai Sharma

26

จากการนำไปใช้กับ Node.js ของ JWT พร้อมด้วยโทเค็นการรีเฟรช :

1) ในกรณีนี้พวกเขาใช้ uid และไม่ใช่ JWT เมื่อรีเฟรชโทเค็นพวกเขาจะส่งโทเค็นการรีเฟรชและผู้ใช้ หากคุณใช้เป็น JWT คุณไม่จำเป็นต้องส่งผู้ใช้เพราะจะอยู่ใน JWT

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

3) ในการใช้งานนี้จะตอบสนองต่อวิธีการเข้าสู่ระบบด้วยทั้งโทเค็นการเข้าถึงและโทเค็นการรีเฟรช ตะเข็บถูกต้องสำหรับฉัน


โดยพูดว่า "1) ในกรณีนี้พวกเขาใช้ uid ... " คุณหมายถึง UUID หรือเปล่า?
ozanmuyes

สิ่งที่เกี่ยวกับการใช้งานที่ง่ายกว่านี้ - ออก JWT - ส่ง JWT ที่เก่ากว่าเมื่อคุณต้องการรีเฟรช - (คุณสามารถตรวจสอบiatกับหน้าต่าง) - ออกใหม่ตามการใช้งานก่อนหน้า
adonese

@adonese โดยส่งเฉพาะที่JWTคุณหมายถึงมีrefresh_tokenภายในหรือไม่ ถ้าเป็นเช่นนั้น OAuth RFC 6749 จะบอกอย่างชัดเจนว่าจะไม่ส่งrefresh_tokenไปยังเซิร์ฟเวอร์ทรัพยากร (และระบบJWTจะส่งไปยังเซิร์ฟเวอร์ทรัพยากร): tools.ietf.org/html/rfc6749#section-1.5
Brenno Costa
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.