คำนำ
เนื่องจาก Angular เป็นแอปพลิเคชันหน้าเดียวทรัพยากรส่วนใหญ่จะถูกโหลดลงในเบราว์เซอร์ตั้งแต่ต้นดังนั้นคุณต้องให้ความสำคัญกับช่วงเวลาของการตรวจสอบและตรวจสอบให้แน่ใจว่ามีเพียงผู้ใช้ที่ผ่านการตรวจสอบเท่านั้นที่สามารถดูอินเทอร์เฟซที่เกี่ยวข้องได้
การรับรองความถูกต้องในบทความนี้หมายถึงวิธีการพิจารณาว่าผู้ใช้ได้ลงชื่อเข้าใช้หรือไม่และตรวจสอบให้แน่ใจว่าความต้องการการตรวจสอบของเซิร์ฟเวอร์สามารถตอบสนองได้ในการสื่อสารทุกครั้งกับเซิร์ฟเวอร์ โปรดทราบว่าไม่รวมการตัดสินว่ามีอำนาจเฉพาะหรือไม่
สำหรับการเข้าสู่ระบบส่วนใหญ่จะยอมรับ ชื่อผู้ใช้และรหัสผ่านของผู้ใช้ ส่งไปยังเซิร์ฟเวอร์เพื่อตรวจสอบ ประมวลผลการตอบสนองการตรวจสอบ และ สร้างข้อมูลการตรวจสอบสิทธิ์ทางฝั่งเบราว์เซอร์
สองวิธีในการใช้งานการตรวจสอบตัวตน
ในปัจจุบันมีสองประเภทหลักของวิธีการที่จะใช้การรับรองความถูกต้องของตัวตน:
คุกกี้
หน้าเว็บเบราว์เซอร์แบบดั้งเดิมใช้คุกกี้เพื่อตรวจสอบตัวตน ในความเป็นจริงในเลเยอร์แอปพลิเคชันของเบราว์เซอร์โดยทั่วไปไม่จำเป็นต้องกังวลเกี่ยวกับการตรวจสอบตัวตน การตั้งค่าคุกกี้เสร็จสมบูรณ์โดยเซิร์ฟเวอร์ เมื่อส่งคำขอเบราว์เซอร์จะแนบข้อมูลคุกกี้ที่เกี่ยวข้องโดยอัตโนมัติ ดังนั้นในรหัส JavaScript ไม่จำเป็นต้องเขียนรหัสพิเศษสำหรับสิ่งนี้ แต่ทุกครั้งที่ฉันร้องขอฉันจะนำข้อมูลคุกกี้ทั้งหมด
ด้วยแอปพลิเคชันของ CDN และอุปกรณ์พกพาที่เพิ่มขึ้นอย่างค่อยเป็นค่อยไปคุกกี้จะไม่สามารถตอบสนองความต้องการการตรวจสอบความถูกต้องหลายโดเมนที่ซับซ้อนได้มากขึ้น
สำคัญ
ในความเป็นจริงการรับรองความถูกต้องตามคีย์ไม่ได้เกิดขึ้นเมื่อเร็ว ๆ นี้มันมีมานานกว่าประวัติของคุกกี้ เมื่อเบราว์เซอร์ร้องขอเซิร์ฟเวอร์จะแนบปุ่มเข้ากับคำขอด้วยวิธีที่เฉพาะเจาะจงเช่นในส่วนหัวของคำขอ ในการทำเช่นนี้จำเป็นต้องเขียนรหัสลูกค้าพิเศษเพื่อการจัดการ
มาตรฐานเว็บคีย์ที่ใช้ JSON (JSON Web Token) ที่เพิ่งเกิดขึ้นเมื่อเร็ว ๆ นี้เป็นการตรวจสอบความถูกต้องทั่วไปโดยใช้คีย์
ในเว็บแอปพลิเคชันหากคุณกำลังสร้าง API คุณควรให้ความสำคัญกับการใช้วิธีการสำคัญ
เข้าสู่ระบบกระบวนการ
เข้าสู่ระบบเป็นขั้นตอนแรกในการตรวจสอบตัวตน โดยการบันทึกข้อมูลการตรวจสอบตัวตนที่สอดคล้องกันเท่านั้นที่สามารถจัดระเบียบได้
ต้องใช้หน้าเข้าสู่ระบบแยกต่างหากหรือไม่?
มีสองวิธีในการจัดการกับหน้าเข้าสู่ระบบ:
หน้าเข้าสู่ระบบแยกต่างหาก จะข้ามไปยังแอปพลิเคชันหน้าเดียวหลังจากเข้าสู่ระบบเสร็จสิ้น สิ่งนี้ช่วยให้การควบคุมการเข้าถึงทรัพยากรของแอปพลิเคชันหน้าเดียวเพื่อป้องกันไม่ให้ผู้ใช้ที่ไม่ใช่โลจินเข้าถึงและเหมาะสำหรับสถานการณ์แอปพลิเคชันของเครื่องมือพื้นหลังหรือเครื่องมือการจัดการ แต่จริง ๆ แล้วมันช่วยลดประสบการณ์การใช้งานของแอปพลิเคชันหน้าเดียว
ดำเนินการเข้าสู่ระบบภายในแอปพลิเคชันหน้าเดียว ซึ่งสอดคล้องกับแนวคิดการออกแบบของแอปพลิเคชันหน้าเดียวและเหมาะสำหรับสถานการณ์ผลิตภัณฑ์ยอดนิยมเนื่องจากคนที่เป็นอันตรายสามารถรับรหัสส่วนหน้าของแอปพลิเคชันหน้าเดียวของคุณได้เสมอ
หน้าเข้าสู่ระบบแยกต่างหาก
โดยทั่วไปการพูดวัตถุประสงค์ของการใช้หน้าเข้าสู่ระบบแยกต่างหากคือการปกป้องหน้าเว็บที่เพิ่มขึ้นหลังจากการเข้าสู่ระบบจากการเข้าถึงโดยผู้ใช้ที่ไม่ระบุชื่อ ดังนั้นในหน้าเข้าสู่ระบบจะมีการสร้างแบบฟอร์มและ ใช้วิธีการส่งการยกย่องแบบดั้งเดิม (ไม่ใช่ AJAX) โดยตรง หลังจากแบ็กเอนด์ตรวจสอบชื่อผู้ใช้และรหัสผ่านได้สำเร็จ HTML ของหน้าแอปพลิเคชันด้านเดียวหลังจากการเข้าสู่ระบบจะถูกส่งออก
ในกรณีนี้คุณสามารถวางข้อมูลการรับรองความถูกต้องโดยตรงในเอาท์พุท HTML ตัวอย่างเช่นคุณสามารถใช้ หยก เพื่อสร้างหน้าเช่นนี้:
<!-dashboard.jade-> doctype htmlhtmlhtml ลิงก์ (rel = "stylesheet", href = "/assets/app.e1c2c6ea9350869264da10de799dced1.css") สคริปต์ร่างกาย window.token =! {json.stringify (โทเค็น)}; Div.MD-Padding (UI-View) สคริปต์ (src = "/assets/app.84b1e53df1b4b23171da.js"))หลังจากการตรวจสอบชื่อผู้ใช้และรหัสผ่านสำเร็จแล้วแบ็กเอนด์สามารถใช้วิธีการต่อไปนี้เพื่อแสดงผลและส่งออก HTML:
return res.render ('dashboard', {โทเค็น: โทเค็น});เมื่อเปิดตัวแอปพลิเคชันเชิงมุมแล้วมันสามารถสื่อสารด้วยการตรวจสอบความถูกต้อง นอกจากนี้ยังช่วยให้มั่นใจได้ว่ามีเพียงผู้ใช้ที่เข้าสู่ระบบได้สำเร็จเท่านั้นที่สามารถเข้าสู่หน้านี้ได้
องค์กรที่เข้าสู่ระบบแอปหน้าเดียว
สำหรับแอพพลิเคชั่นเชิงมุมหลายมุมมองการกำหนดเส้นทางจะใช้โดยทั่วไป ภายในหน้าโดยทั่วไปจะมีเมนูแถบด้านข้างคงที่หรือเมนูนำทางด้านบนและพื้นที่ข้อความถูกควบคุมโดยโมดูลการกำหนดเส้นทาง
รหัสตัวอย่างต่อไปนี้ใช้วัสดุเชิงมุมเพื่อจัดระเบียบหน้าและโมดูลการกำหนดเส้นทางใช้ UI-Router เมื่อแอปพลิเคชันเปิดขึ้นจะมีแอนิเมชั่นโหลดพิเศษ หลังจากการโหลดเสร็จสมบูรณ์หน้าที่แสดงจะถูกใช้โดยคอนโทรลเลอร์ AppController สำหรับผู้ใช้ที่ไม่ได้ลงชื่อเข้าใช้แบบฟอร์มการเข้าสู่ระบบจะปรากฏขึ้น หลังจากการเข้าสู่ระบบเสร็จสิ้นแล้วหน้าจะแบ่งออกเป็นสามส่วน: หนึ่งคือการนำทาง breadcrumb ชั้นนำ ที่สองคือเมนูแถบด้านข้าง และอีกส่วนหนึ่งเป็น ส่วนหลักของการควบคุมเส้นทาง
รหัสมีดังนี้:
<body ng-app = "app" layout = "row"> <div id = "โหลด"> <!-พรอมต์โหลดหน้า-> </div> <div flex layout = "row" ng-cloak ng-controller = "appcontroller" ng-init = "โหลด ()"> <div ng-if = "isuserauth" <!-loginform-> </div> <div ng-if = "isuserauth" layout flex = "row"> <md-sidenav flex = "15" md-is-locked-open = "true"> <! </md-toolbar> <md-content> <!-การกำหนดเส้นทาง-> <div ui-view> </div> </md-content> </md-content> </div> </div> </body>
สำหรับการโหลดภาพเคลื่อนไหวพวกเขาอยู่นอก AppController และสามารถซ่อนอยู่ในรหัส AppController สิ่งนี้บรรลุวัตถุประสงค์ในการโหลดหายไปหลังจากโหลด CSS/JavaScript ทั้งหมด
มี isUserAuth ใน AppController มันเป็น false เมื่อเริ่มต้น เมื่อข้อมูลเซสชันที่เก็บไว้ในพื้นที่ถูกต้องหรือหลังจากการเข้าสู่ระบบเสร็จสิ้นค่านี้จะถูกตั้งค่าเป็น ture เนื่องจากการควบคุม ng-if วัตถุประสงค์ของการซ่อนแบบฟอร์มการเข้าสู่ระบบและการแสดงเนื้อหาแอปพลิเคชันสามารถทำได้ ควรสังเกตว่าโดยการใช้ ng-if แทนที่จะเป็น ng-show/ng-hide ที่นี่อดีตจะลบและเพิ่มองค์ประกอบ DOM อย่างแท้จริงในขณะที่หลังจะปรับเปลี่ยนแอตทริบิวต์ CSS ขององค์ประกอบ DOM เท่านั้น สิ่งนี้สำคัญมาก ด้วยวิธีนี้เราสามารถตรวจสอบได้ว่าหลังจากเข้าสู่ระบบเนื้อหาในแอปพลิเคชันหน้าเดียวจะถูกโหลดเพื่อป้องกันรหัสคอนโทรลเลอร์ในเส้นทางปัจจุบันจากการถูกดำเนินการโดยตรงก่อนเข้าสู่ระบบ
ทำไมลูกค้าถึงเข้ารหัสรหัสผ่าน
กระบวนการเข้าสู่ระบบในอุดมคติตามชื่อผู้ใช้และรหัสผ่านมีดังนี้:
1. ด้านเบราว์เซอร์ได้รับรหัสผ่านที่ป้อนโดยผู้ใช้ใช้อัลกอริทึมการแฮชเช่น MD5 เพื่อสร้างรหัสผ่านใหม่ที่มีความยาวคงที่เช่น md5(username + md5(md5(password))) จากนั้นส่งค่าแฮชรหัสผ่าน
2. แบ็กเอนด์ได้รับเกลือที่เกี่ยวข้องตามชื่อผู้ใช้ใช้ชื่อผู้ใช้และรหัสผ่านค่าแฮชคำนวณ ciphertext และค้นหาฐานข้อมูลตามชื่อผู้ใช้และรหัสผ่าน
3. หากการสืบค้นสำเร็จให้สร้างคีย์ให้กลับไปที่เบราว์เซอร์และดำเนินการขั้นตอนที่ 4
4. แบ็กเอนด์สร้างเกลือใหม่และสร้าง ciphertext ใหม่ตามเกลือใหม่และค่าแฮชรหัสผ่านที่ส่งโดยเบราว์เซอร์ อัปเดตเกลือและ ciphertext ในฐานข้อมูล
บางที 80% ของผู้คนไม่สามารถเข้าใจได้ว่าทำไมการเข้าสู่ระบบจึงซับซ้อนมาก สิ่งนี้อาจต้องใช้บทความพิเศษเพื่ออธิบายอย่างชัดเจน ที่นี่ฉันจะอธิบายก่อนว่าทำไมเบราว์เซอร์จึงแฮชรหัสผ่านและเหตุผลมีดังนี้:
1. ปกป้องรหัสผ่านของผู้ใช้จากแหล่งที่มาเพื่อให้แน่ใจว่าโดยการทำบันทึกคีย์เท่านั้นคุณจะได้รับรหัสผ่านเดิมของผู้ใช้
2. แม้ว่าเครือข่ายจะถูกดักฟังและไม่ได้ใช้ HTTPS รหัสผ่านที่ถูกขโมยนั้นเป็นหลังจากการแฮชซึ่งอาจส่งผลกระทบต่อข้อมูลของผู้ใช้บนเซิร์ฟเวอร์นี้มากที่สุดและไม่ส่งผลกระทบต่อเว็บไซต์อื่น ๆ ที่ใช้รหัสผ่านเดียวกัน
3. แม้แต่เจ้าของเซิร์ฟเวอร์ก็ไม่สามารถรับรหัสผ่านดั้งเดิมของผู้ใช้ได้
วิธีการนี้ทำให้ความเสี่ยงที่ใหญ่ที่สุดสำหรับผู้ใช้และข้อมูลในแอปพลิเคชันปัจจุบันถูกขโมย ช่วงการสูญเสียจะไม่ถูกขยายและจะไม่มีปัญหาใด ๆ กับ CSDN หรือสตรีมอื่น ๆ
เข้าสู่ระบบการแจ้งเตือนที่ประสบความสำเร็จ
สำหรับบางแอปพลิเคชันไม่ใช่ทุกหน้าต้องการให้ผู้ใช้เข้าสู่ระบบพวกเขาอาจต้องเข้าสู่ระบบเมื่อทำการดำเนินการบางอย่าง ในกรณีนี้หลังจากเข้าสู่ระบบแอปพลิเคชันทั้งหมดจะต้องได้รับแจ้ง สิ่งนี้ช่วยให้คุณใช้ฟังก์ชั่นการออกอากาศ
รหัสง่าย ๆ มีดังนี้:
Angular .Module ('App') .Controller ('LoginController', ['$ rootscope', LoginController]); ฟังก์ชั่น loginController ($ rootscope) {// ฟังก์ชั่นที่เรียกว่า amfterloginsuccess () {$ rootscope -ในคอนโทรลเลอร์อื่น ๆ คุณสามารถฟังการออกอากาศนี้และดำเนินการที่ต้องดำเนินการหลังจากการเข้าสู่ระบบสำเร็จเช่นการได้รับรายการหรือรายละเอียด:
$ scope. $ on ('user.login.success', ฟังก์ชั่น (ด้ามจับ, ข้อมูล) {// การประมวลผล});ข้อมูลการรับรองความถูกต้องของข้อมูลประจำตัว
หลังจากเข้าสู่ระบบได้สำเร็จเซิร์ฟเวอร์จะส่งคืนคีย์และคำขอ API ที่ตามมาจำเป็นต้องนำคีย์และการตอบกลับที่ส่งคืนโดยคำขอจะต้องตรวจสอบว่าเป็นข้อผิดพลาดเกี่ยวกับความไม่ถูกต้องของข้อมูลตัวตนหรือไม่ ชุดงานนี้ค่อนข้างยุ่งยากและควรจะเสร็จสมบูรณ์โดยอัตโนมัติ
บันทึก
มีวิธีการบันทึกคีย์ดังต่อไปนี้โดยประมาณ:
1.Cookies: ดังที่ได้กล่าวไว้ก่อนหน้านี้ไม่แนะนำ ในขณะเดียวกันก็มีขีด จำกัด สูงสุด 4K
2.SessionStorage: หน้าแท็บนั้นถูกต้อง เมื่อปิดหรือเปิดหน้าแท็บใหม่จะไม่สามารถใช้ร่วมกันได้
3.LocalStorage: วิธีการจัดเก็บในอุดมคติ ข้อมูลที่เก็บไว้ใน LocalStorage จะมีอยู่เสมอ
4. บริการ Singleton Angular: หากเก็บไว้ในแอปพลิเคชันข้อมูลจะหายไปหลังจากสดชื่นและแน่นอนว่ามันไม่สามารถแชร์ระหว่างหน้าแท็บได้
วิธีการที่ดีกว่าคือข้อมูลการตรวจสอบสิทธิ์จะถูกเก็บไว้ใน LocalStorage แต่จะเริ่มต้นเป็นบริการ Singleton ของ Angular เมื่อแอปพลิเคชันเริ่มต้นขึ้น
เพิ่มข้อมูลการรับรองความถูกต้องในคำขอ
วัตถุประสงค์ของข้อมูลการรับรองความถูกต้องของตัวตนคือการระบุตัวตนของเซิร์ฟเวอร์และรับข้อมูล ดังนั้นจึงจำเป็นต้องมีข้อมูลการตรวจสอบสิทธิ์เพิ่มเติมในคำขอ
ในแอปพลิเคชันทั่วไปข้อมูลการตรวจสอบจะถูกวางไว้ในส่วนหัวของคำขอ หากคุณตั้งส่วนหัวทีละครั้งในแต่ละคำขอมันจะใช้เวลานานเกินไปและลำบาก $httpProvider ใน Angular ให้ interceptors interceptor ซึ่งการประมวลผลแบบครบวงจรของการร้องขอและการตอบสนองทุกครั้งสามารถทำได้
วิธีการเพิ่มตัวดักมีดังนี้:
Angular .Module ('App') .config (['$ httpprovider', ฟังก์ชั่น ($ httpprovider) {$ httpprovider.interceptors.push (httpinterceptor);}]); คำจำกัดความของ HttpInterceptor มีดังนี้:
Angular .Module ('App') .Factory ('httpinterceptor', ['$ q', httpinterceptor]); ฟังก์ชั่น httpinterceptor ($ q) {return {// ก่อนที่จะมีการออกคำขอ } return config; }, // มีข้อผิดพลาดเกิดขึ้นในขณะที่ร้องขอออกคำสั่ง: ฟังก์ชั่น (err) {return $ q.reject (err); }, // การตอบสนองการตอบสนอง: ฟังก์ชั่น (res) {return res; }, // ข้อผิดพลาดในการตอบกลับที่ส่งคืนรวมถึงเมื่อแบ็กเอนด์ส่งคืนการตอบกลับรหัสสถานะ HTTP ของไม่ใช่ 200 ถูกตั้งค่า: ฟังก์ชัน (ERR) {return $ q.reject (ERR); -Interceptors ให้การประมวลผลวัฏจักรชีวิตเต็มรูปแบบจากการร้องขอไปยังการตอบกลับการส่งคืนซึ่งโดยทั่วไปสามารถใช้ทำสิ่งต่อไปนี้:
1. เพิ่มข้อมูลลงในคำขอที่ออกอย่างสม่ำเสมอเช่นการเพิ่มข้อมูลการตรวจสอบสิทธิ์
2. การจัดการข้อผิดพลาดแบบครบวงจรรวมถึงข้อผิดพลาดเมื่อมีการออกคำขอ (เช่นเครือข่ายในด้านเบราว์เซอร์ไม่ได้เชื่อมต่อ) และข้อผิดพลาดเมื่อการตอบกลับถูกส่งคืน
3. การประมวลผลการตอบสนองแบบครบวงจรเช่นแคชข้อมูลบางอย่าง ฯลฯ
4. แสดงแถบความคืบหน้าคำขอ
ในรหัสตัวอย่างข้างต้นเมื่อ localStorage มี token ค่าค่า token จะถูกเพิ่มที่หัวของแต่ละคำขอ
ความล้มเหลวและการจัดการ
โดยทั่วไปแบ็กเอนด์ควรตั้งค่ารหัสสถานะ HTTP ตอบกลับเป็น 401 เมื่อการตรวจสอบ token ล้มเหลวเพื่อให้สามารถจัดการได้อย่างสม่ำเสมอใน responseError Interceptor:
ResponseError: ฟังก์ชั่น (err) {ถ้า (-1 === err.status) {// เซิร์ฟเวอร์ระยะไกลไม่ตอบสนอง} อื่นถ้า (401 === err.status) {// ข้อผิดพลาด 401 มักใช้สำหรับความล้มเหลวของการตรวจสอบความถูกต้อง ขึ้นอยู่กับข้อผิดพลาดที่เกิดขึ้นโดยแบ็กเอนด์เมื่อการตรวจสอบความถูกต้องล้มเหลว} อื่นถ้า (404 === err.status) {// เซิร์ฟเวอร์ส่งคืน 404} ส่งคืน $ q.reject (err);}สรุป
ในความเป็นจริงตราบใดที่รหัสสถานะที่ส่งคืนโดยเซิร์ฟเวอร์ไม่ใช่ 200 responseError จะถูกเรียก ที่นี่ข้อผิดพลาดสามารถจัดการได้อย่างสม่ำเสมอและแสดง
เนื้อหาข้างต้นเกี่ยวข้องกับการเข้าสู่ระบบและการตรวจสอบตัวตนในแอปพลิเคชันการพัฒนาเชิงมุม ฉันหวังว่ามันจะเป็นประโยชน์สำหรับทุกคนในการเรียนรู้เชิงมุม