คำถามนี้ได้รับการแก้ไขแล้วในรูปแบบที่แตกต่างกันเล็กน้อยที่นี่:
รับรองความถูกต้องสงบ
แต่สิ่งนี้จะอยู่จากฝั่งเซิร์ฟเวอร์ ลองดูที่นี่จากลูกค้าฝั่ง แม้ว่าก่อนที่เราจะทำเช่นนั้นมีโหมโรงที่สำคัญ:
Javascript Crypto ไม่มีความหวัง
บทความของ Matasano เกี่ยวกับเรื่องนี้มีชื่อเสียง แต่บทเรียนในนั้นมีความสำคัญมาก:
https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful/
เพื่อสรุป:
- การโจมตีคนกลางคนสามารถเปลี่ยนรหัส crypto ของคุณได้เล็กน้อย
<script>
function hash_algorithm(password){ lol_nope_send_it_to_me_instead(password); }</script>
- การโจมตีจากคนกลางนั้นไม่สำคัญกับหน้าเว็บที่ให้บริการทรัพยากรใด ๆ ผ่านการเชื่อมต่อที่ไม่ใช่ SSL
- เมื่อคุณมี SSL คุณจะใช้ crypto จริง ๆ
และเพื่อเพิ่มข้อพิสูจน์ของฉันเอง:
- การโจมตี XSS ที่ประสบความสำเร็จอาจส่งผลให้ผู้โจมตีเรียกใช้รหัสบนเบราว์เซอร์ของลูกค้าแม้ว่าคุณจะใช้ SSL - ดังนั้นแม้ว่าคุณจะได้รับการแฮ็กทุกครั้งที่การโจมตีล้มลง crypto เบราว์เซอร์ของคุณ รหัสจาวาสคริปต์ในเบราว์เซอร์ของผู้อื่น
วิธีนี้จะทำให้แผนการรับรองความถูกต้อง RESTful จำนวนมากเป็นไปไม่ได้หรือไร้สาระหากคุณต้องการใช้ไคลเอนต์ JavaScript มาดูกัน!
HTTP การรับรองความถูกต้องเบื้องต้น
HTTP Auth ขั้นพื้นฐานและสำคัญที่สุด รูปแบบที่ง่ายที่สุด: เพียงแค่ส่งชื่อและรหัสผ่านทุกคำขอ
แน่นอนว่าต้องใช้ SSL อย่างแน่นอนเพราะคุณผ่านชื่อและรหัสผ่าน Base64 (ย้อนกลับ) ที่เข้ารหัสได้ทุกคำขอ ทุกคนที่ฟังในบรรทัดสามารถแยกชื่อผู้ใช้และรหัสผ่านได้เล็กน้อย อาร์กิวเมนต์ "การรับรองความถูกต้องพื้นฐานไม่ปลอดภัย" ส่วนใหญ่มาจากสถานที่ของ "การรับรองความถูกต้องพื้นฐานผ่าน HTTP" ซึ่งเป็นแนวคิดที่น่ากลัว
เบราว์เซอร์ให้การสนับสนุนการรับรองความถูกต้องพื้นฐาน HTTP ในเบราว์เซอร์ แต่มันก็น่าเกลียดเหมือนบาปและคุณอาจไม่ควรใช้มันสำหรับแอปของคุณ อย่างไรก็ตามทางเลือกคือการซ่อนชื่อผู้ใช้และรหัสผ่านใน JavaScript
นี่เป็นทางออกที่สงบที่สุด เซิร์ฟเวอร์ไม่จำเป็นต้องมีความรู้เกี่ยวกับสิ่งใด ๆ และรับรองความถูกต้องของการโต้ตอบกับผู้ใช้แต่ละคน ผู้ที่ชื่นชอบ REST บางคน (ส่วนใหญ่เป็นชาวฟาง) ยืนยันว่าการรักษาสถานะใด ๆ นั้นเป็นเรื่องนอกรีตและจะโกรธถ้าคุณคิดถึงวิธีการพิสูจน์ตัวตนแบบอื่น ๆ มีประโยชน์ทางทฤษฎีสำหรับการปฏิบัติตามมาตรฐานประเภทนี้ - สนับสนุนโดย Apache นอกกรอบ - คุณสามารถจัดเก็บวัตถุของคุณเป็นไฟล์ในโฟลเดอร์ที่ป้องกันด้วยไฟล์. htaccess หากหัวใจของคุณต้องการ!
มีปัญหาเหรอ? คุณแคชชื่อผู้ใช้และรหัสผ่านในฝั่งไคลเอ็นต์ สิ่งนี้ทำให้ evil.ru แตกได้ดีขึ้น - แม้แต่ช่องโหว่ XSS พื้นฐานที่สุดอาจส่งผลให้ลูกค้ายิ้มแย้มชื่อผู้ใช้และรหัสผ่านของเขาไปยังเซิร์ฟเวอร์ที่ชั่วร้าย คุณอาจจะพยายามที่จะบรรเทาความเสี่ยงนี้โดย hashing และเกลือรหัสผ่าน แต่จำไว้: JavaScript Crypto สิ้นหวัง คุณสามารถลดความเสี่ยงนี้ได้โดยปล่อยให้มันรองรับการตรวจสอบขั้นพื้นฐานของเบราว์เซอร์ แต่ .. น่าเกลียดเหมือนบาปดังที่ได้กล่าวไว้ก่อนหน้านี้
HTTP Digest Auth
การตรวจสอบ Digest นั้นสามารถทำได้ด้วย jQuery หรือไม่?
การรับรองความปลอดภัยเพิ่มเติมที่ปลอดภัยนี่คือความท้าทายแฮชคำขอ / ตอบกลับ ยกเว้นJavaScript Crypto สิ้นหวังจึงทำงานผ่าน SSL เท่านั้นและคุณยังคงมีการแคชชื่อผู้ใช้และรหัสผ่านบนฝั่งไคลเอ็นต์ทำให้มันซับซ้อนมากขึ้นกว่า HTTP ตรวจสอบสิทธิ์พื้นฐาน แต่ไม่มีความปลอดภัยมากขึ้น
การตรวจสอบข้อความค้นหาด้วยพารามิเตอร์ลายเซ็นเพิ่มเติม
รับรองความถูกต้องอีก "ปลอดภัย" ที่คุณเข้ารหัสพารามิเตอร์ของคุณด้วยข้อมูลที่ไม่ใช่และเวลา (เพื่อป้องกันการโจมตีซ้ำและเวลา) และส่ง หนึ่งในตัวอย่างที่ดีที่สุดคือโพรโทคอล OAuth 1.0 ซึ่งเท่าที่ฉันรู้วิธีการตรวจสอบสิทธิ์ที่เชื่อถือได้บนเซิร์ฟเวอร์ REST
http://tools.ietf.org/html/rfc5849
โอ้ แต่ไม่มีลูกค้า OAuth 1.0 สำหรับ JavaScript ทำไม?
JavaScript Crypto นั้นสิ้นหวังอย่าลืม JavaScript ไม่สามารถเข้าร่วมได้โดยไม่ต้องใช้ OAuth 1.0 SSL และคุณยังต้องเก็บชื่อผู้ใช้และรหัสผ่านของลูกค้าในประเทศ - ซึ่งทำให้ในประเภทเดียวกับ Digest Auth - มันซับซ้อนมากขึ้นกว่า HTTP ตรวจสอบสิทธิ์พื้นฐาน แต่ก็ไม่มีความปลอดภัยมากขึ้น
เหรียญ
ผู้ใช้ส่งชื่อผู้ใช้และรหัสผ่านและในการแลกเปลี่ยนจะได้รับโทเค็นที่สามารถใช้ในการตรวจสอบคำขอ
นี่คือความปลอดภัยเล็กน้อยกว่าการรับรองความถูกต้องพื้นฐาน HTTP เนื่องจากทันทีที่ธุรกรรมชื่อผู้ใช้ / รหัสผ่านเสร็จสมบูรณ์คุณสามารถละทิ้งข้อมูลที่ละเอียดอ่อนได้ นอกจากนี้ยังมี RESTful น้อยกว่าเนื่องจากโทเค็นประกอบด้วย "สถานะ" และทำให้การติดตั้งเซิร์ฟเวอร์นั้นซับซ้อนยิ่งขึ้น
SSL ยัง
ถึงแม้ว่าคุณจะต้องส่งชื่อผู้ใช้และรหัสผ่านเริ่มต้นเพื่อรับโทเค็น ข้อมูลที่ละเอียดอ่อนยังคงสัมผัสจาวาสคริปต์ที่ยอมให้
เพื่อปกป้องข้อมูลประจำตัวของผู้ใช้คุณยังต้องป้องกันจาวาสคริปต์ของคุณและคุณยังต้องส่งชื่อผู้ใช้และรหัสผ่าน จำเป็นต้องใช้ SSL
โทเค็นหมดอายุ
เป็นเรื่องปกติที่จะบังคับใช้นโยบายโทเค็นเช่น "เฮ้เมื่อโทเค็นนี้ยาวเกินไปให้ละทิ้งและทำให้ผู้ใช้รับรองความถูกต้องอีกครั้ง" หรือ "ฉันค่อนข้างแน่ใจว่าที่อยู่ IP เดียวที่ได้รับอนุญาตให้ใช้โทเค็นนี้คือXXX.XXX.XXX.XXX
" นโยบายเหล่านี้เป็นแนวคิดที่ดีทีเดียว
Firesheeping
อย่างไรก็ตามการใช้โทเค็นที่ไม่มี SSL ยังคงเสี่ยงต่อการถูกโจมตีที่เรียกว่า 'sidejacking': http://codebutler.github.io/firesheep/
ผู้โจมตีไม่ได้รับข้อมูลรับรองผู้ใช้ของคุณ แต่พวกเขายังสามารถแสร้งเป็นผู้ใช้ของคุณซึ่งอาจไม่ดีนัก
tl; dr: การส่งโทเค็นที่ไม่ได้เข้ารหัสผ่านสายหมายความว่าผู้โจมตีสามารถจับโทเค็นเหล่านั้นได้อย่างง่ายดายและแกล้งทำเป็นเป็นผู้ใช้ของคุณ FireSheep เป็นโปรแกรมที่ทำให้ง่ายมาก
แยกโซนปลอดภัยมากขึ้น
ยิ่งแอปพลิเคชันที่คุณใช้มีขนาดใหญ่ขึ้นจะยิ่งทำให้แน่ใจได้ว่าแอปพลิเคชันจะไม่สามารถฉีดโค้ดบางอย่างที่เปลี่ยนวิธีการประมวลผลข้อมูลที่ละเอียดอ่อนของคุณได้ คุณเชื่อมั่นใน CDN ของคุณหรือไม่? ผู้โฆษณาของคุณ? ฐานรหัสของคุณเอง?
ทั่วไปสำหรับรายละเอียดบัตรเครดิตและน้อยกว่าสำหรับชื่อผู้ใช้และรหัสผ่าน - ผู้ดำเนินการบางคนเก็บ 'การป้อนข้อมูลที่ละเอียดอ่อน' ในหน้าแยกจากส่วนที่เหลือของแอปพลิเคชันของพวกเขาหน้าเว็บที่สามารถควบคุมและล็อคอย่างแน่นหนา เป็นการยากที่จะหลอกลวงผู้ใช้ด้วย
คุกกี้ (หมายถึง Token)
เป็นไปได้ (และทั่วไป) เพื่อใส่โทเค็นการรับรองความถูกต้องในคุกกี้ สิ่งนี้ไม่เปลี่ยนคุณสมบัติใด ๆ ของการรับรองความถูกต้องด้วยโทเค็นมันเป็นสิ่งที่สะดวกกว่า อาร์กิวเมนต์ก่อนหน้านี้ทั้งหมดยังคงมีผลอยู่
เซสชัน (ยังหมายถึง Token)
Session Auth เป็นเพียงการรับรองความถูกต้องของ Token แต่มีความแตกต่างเล็กน้อยที่ทำให้ดูเหมือนเป็นสิ่งที่แตกต่างกันเล็กน้อย:
- ผู้ใช้เริ่มต้นด้วยโทเค็นที่ไม่ได้รับการรับรองความถูกต้อง
- ส่วนหลังรักษาวัตถุ 'สถานะ' ที่เชื่อมโยงกับโทเค็นของผู้ใช้
- โทเค็นมีให้ในคุกกี้
- สภาพแวดล้อมของแอปพลิเคชั่นจะแยกรายละเอียดออกไป
นอกเหนือจากนั้นมันไม่แตกต่างจาก Token Auth จริงๆ
สิ่งนี้เดินไกลจากการใช้งาน RESTful - ด้วยออบเจ็กต์สถานะที่คุณกำลังจะทำต่อไปและเดินไปตามเส้นทางของ ol ol 'RPC ธรรมดาบนเซิร์ฟเวอร์ stateful
OAuth 2.0
OAuth 2.0 ดูที่ปัญหาของ "ซอฟต์แวร์ A อนุญาตให้ Software B เข้าถึงข้อมูลของ User X ได้อย่างไรโดยไม่ต้องซอฟต์แวร์ B มีสิทธิ์เข้าถึงข้อมูลรับรองการเข้าสู่ระบบของ User X"
การนำไปใช้นั้นเป็นวิธีมาตรฐานอย่างมากสำหรับผู้ใช้ในการรับโทเค็นจากนั้นสำหรับบริการของบุคคลที่สามที่จะไป "อ๋อผู้ใช้รายนี้และการจับคู่โทเค็นนี้และคุณสามารถรับข้อมูลบางส่วนจากเราได้"
โดยพื้นฐานแล้ว OAuth 2.0 เป็นเพียงโปรโตคอลโทเค็น มันแสดงคุณสมบัติเช่นเดียวกับโปรโตคอลโทเค็นอื่น ๆ - คุณยังต้องใช้ SSL เพื่อปกป้องโทเค็นเหล่านั้น - มันแค่เปลี่ยนวิธีสร้างโทเค็นเหล่านั้น
มีสองวิธีที่ OAuth 2.0 สามารถช่วยคุณได้:
- การให้การรับรองความถูกต้อง / ข้อมูลแก่ผู้อื่น
- รับการรับรองความถูกต้อง / ข้อมูลจากผู้อื่น
แต่เมื่อมันลงมาคุณแค่ ... ใช้โทเค็น
กลับไปที่คำถามของคุณ
ดังนั้นคำถามที่คุณถามคือ "ฉันควรเก็บโทเค็นของฉันไว้ในคุกกี้และให้การจัดการเซสชันอัตโนมัติของสภาพแวดล้อมดูแลรายละเอียดหรือฉันควรเก็บโทเค็นของฉันใน Javascript และจัดการรายละเอียดเหล่านั้นด้วยตนเอง"
และคำตอบคือ: ทำสิ่งที่ทำให้คุณมีความสุข
แต่สิ่งที่เกี่ยวกับการจัดการเซสชันอัตโนมัติคือว่ามีสิ่งมหัศจรรย์เกิดขึ้นมากมายเบื้องหลังคุณ บ่อยครั้งที่มันดีกว่าที่จะสามารถควบคุมรายละเอียดเหล่านั้นได้
ฉันอายุ 21 ดังนั้น SSL คือใช่
คำตอบอื่น ๆ คือ: ใช้ https สำหรับทุกสิ่งหรือกลุ่มที่จะขโมยรหัสผ่านและโทเค็นของผู้ใช้ของคุณ