ความแตกต่างระหว่าง CanLoad ของ Angular และ canActivate?


100

อะไรคือความแตกต่างระหว่างcanLoadและcanActivate?

export interface Route {
  path?: string;
  pathMatch?: string;
  matcher?: UrlMatcher;
  component?: Type<any>;
  redirectTo?: string;
  outlet?: string;
  canActivate?: any[];
  canActivateChild?: any[];
  canDeactivate?: any[];
  canLoad?: any[];
  data?: Data;
  resolve?: ResolveData;
  children?: Routes;
  loadChildren?: LoadChildren;
}

เมื่อใดที่ฉันควรเลือกอันใด

คำตอบ:


99

canActivateใช้เพื่อป้องกันไม่ให้ผู้ใช้ที่ไม่ได้รับอนุญาตเข้าถึงเส้นทางบางเส้นทาง ดูเอกสารสำหรับข้อมูลเพิ่มเติม

canLoadใช้เพื่อป้องกันไม่ให้แอปพลิเคชันโหลดโมดูลทั้งหมดอย่างเฉื่อยชาหากผู้ใช้ไม่ได้รับอนุญาตให้ทำเช่นนั้น

ดูเอกสารและตัวอย่างด้านล่างสำหรับข้อมูลเพิ่มเติม

{
    path: 'admin',
    loadChildren: 'app/admin/admin.module#AdminModule',
    canLoad: [AuthGuard]
},

ด้วยรหัสนี้รหัสสำหรับ AdminModule trueจะถูกโหลดลงในใบสมัครเท่านั้นถ้าผลตอบแทน

หากผู้ใช้ไม่ได้รับอนุญาตให้เข้าถึงเส้นทางนี้และเราใช้เพียงcanActivateยามเท่านั้นระบบAdminModuleจะโหลดแม้ว่าผู้ใช้จะไม่สามารถเข้าถึงเส้นทางนั้นได้


6
หากใช้canActivateในสถานการณ์ข้างต้นจะมีความแตกต่างอย่างไร
k11k2

3
@ k11k2 พร้อมcanActiveโมดูลจะโหลด (F12> Sources - ใน chrome) คุณสามารถเห็นไฟล์. js ที่นั่นด้วยcanLoadโมดูลเหล่านี้ (ไฟล์. js) จะไม่ถูกโหลด :) ตรวจสอบคำตอบของฉันด้านบนที่ฉันอธิบายไว้ดีกว่า
DiPix

23
สิ่งที่เกี่ยวกับสถานการณ์ที่ผู้ดูแลระบบเข้าสู่ระบบดังนั้นโมดูลผู้ดูแลระบบจึงถูกโหลดโดยcanLoadส่งคืนค่าจริงจากนั้นจึงออกจากระบบแอปพลิเคชัน ตอนนี้ผู้ใช้ที่ไม่ใช่ผู้ดูแลระบบเข้าสู่ระบบในเบราว์เซอร์เดียวกันมันทำงานอย่างไร? โมดูลที่โหลดถูกขับไล่หรือลบออกจากแคชหรือไม่?
Keerthivasan

2
@Keerthivasan ไม่มีอะไรบังคับให้ลบส่วน AdminModule ที่เกียจคร้านที่โหลดไว้ก่อนหน้านี้เมื่อผู้ใช้ออกจากระบบและลงชื่อเข้าใช้อีกครั้งด้วยบัญชีอื่นซึ่งไม่มีสิทธิ์เพียงพอที่จะโหลด AdminModule อย่างไรก็ตามคุณจะไม่สามารถเข้าถึงได้เลย .. ยกเว้นมีโมดูลแคชที่โหลดไว้ ฉันไม่คิดว่ามันเป็นปัญหาด้านความปลอดภัยที่แท้จริงเนื่องจากโดยปกติแล้วอุปกรณ์หนึ่งเครื่องจะเป็นผู้ใช้จริง
hastrb

1
@ sgClaudia98 คุณสามารถใช้ได้ทั้งสองอย่าง แต่มีคำสั่งเข้มงวดในการประหารชีวิตผู้คุม ด้วยเหตุนี้จึงไม่ทำให้เกิดความแตกต่างในกรณีของคุณเกี่ยวกับสิ่งที่ฉันได้กล่าวไว้ก่อนหน้านี้เล็กน้อย ฉันคิดว่าฉันใส่คำอธิบายโดยละเอียดไว้ในความคิดเห็นแรกของฉัน นั่นจะเป็นกรณีที่ค่อนข้างแปลกหากมีอุปกรณ์หนึ่งเครื่องและผู้ดูแลระบบ / ไม่ใช่ผู้ดูแลระบบเข้าสู่ระบบทีละคนในปัจจุบัน
hastrb

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

นี่คือการทดสอบที่ฉันทำกับยามทั้งสองด้วยโมดูลคุณลักษณะที่ขี้เกียจโหลด:

1. CanActivate Guard Test

คุณจะสังเกตเห็นที่ด้านล่างของหน้าเครือข่ายว่ามีคำขอ 24 รายการโดยมีขนาด 9.5 MB โอนเสร็จใน 3.34 วินาทีและโหลดเต็มที่ใน 3.47 วินาที

CanActivate Guard Test ในโมดูลฟีเจอร์ Lazy Loaded

1. การทดสอบ CanLoad Guard

ที่นี่คุณจะเห็นความแตกต่างอย่างมากเมื่อเราใช้ CanLoad Guard เป็นเบราว์เซอร์ที่สร้างคำขอเพียง 18 รายการโดยมีขนาด 9.2 MB ที่ถ่ายโอนเสร็จสิ้นใน 2.64 วินาทีและโหลดเต็มที่ 2.59 วินาที

การทดสอบ CanLoad Guard ในโมดูลฟีเจอร์ Lazy Loaded

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

เคล็ดลับ: หากคุณต้องการทำการทดสอบในโครงการของคุณตรวจสอบให้แน่ใจว่าได้Disable Cacheเลือกช่องทำเครื่องหมายในแท็บเครือข่ายแล้วจะมีการทำเครื่องหมายในภาพแรก


3
เพียงเพื่อไม่ให้ใครบางคนสับสน .. 403 คือ Forbbiden ไม่ใช่ Unauthorized ซึ่งก็คือ 401
hastrb

20

เกี่ยวกับคำถามจากความคิดเห็นในโพสต์อื่น ๆ "ถ้าฉันใช้ canActivate ในสถานการณ์ข้างต้นจะแตกต่างกันอย่างไร"

จริงๆแล้วสำหรับผู้ใช้จะไม่มีความแตกต่างเขาจะไม่สามารถเข้าถึงเพจได้ในทั้งสองกรณี แม้ว่าจะมีความแตกต่างหนึ่งที่ซ่อนอยู่ หากคุณกด F12 และย้ายไปที่ Sources (ใน Chrome) ซึ่งจะดาวน์โหลดไฟล์ จากนั้นคุณจะเห็นว่าในกรณีที่ดาวน์โหลดไฟล์canActiveพร้อมรหัสแล้ว ( chunk.js ) แม้ว่าคุณจะไม่มีสิทธิ์เข้าถึงเพจก็ตาม ป้อนคำอธิบายภาพที่นี่

แต่ในกรณีที่canLoadจะไม่มีไฟล์chunk.jsพร้อมซอร์สโค้ด

ป้อนคำอธิบายภาพที่นี่

ดังที่คุณเห็นสิ่งนี้มีผลกระทบอย่างมากต่อความปลอดภัย

และแน่นอนอย่าลืมว่าcanLoadสามารถใช้ได้กับLazyLoaded Modulesเท่านั้น


3
ไม่เห็นชิ้นส่วนใด ๆ สำหรับโมดูลการโหลดแบบขี้เกียจในแท็บเครือข่ายของฉัน แต่เส้นทางทำงานตามที่คาดไว้ฉันจะยืนยันได้อย่างไรว่าโมดูลของฉันโหลดตามความต้องการหรือไม่
k11k2

@ k11k2 หากคุณต้องการดูว่าไฟล์ใดที่โมดูลเป็นส่วนหนึ่งของเพียงแค่เพิ่มdebugger;คำสั่งในตัวสร้างสำหรับส่วนประกอบใดส่วนประกอบหนึ่งในโมดูลนั้น จากนั้นคุณสามารถดูได้ว่าโหลดเป็นกลุ่มแยกต่างหากหรือรวมอยู่ในโมดูลเช่น main หากคุณมีการอ้างอิงถึงส่วนประกอบในโมดูลขี้เกียจที่ไม่ได้แยกออกจากโมดูลนั้นอาจมีการโหลดต่อไป หากคุณเห็นสิ่งนี้แสดงว่าคุณกำลังกรองโดยสิ่งอื่นที่ไม่ใช่ไฟล์ JS หรือคุณต้องแยกโมดูลขี้เกียจออกเป็นส่วนทั่วไปและส่วนที่ 'ขี้เกียจอย่างแท้จริง'
Simon_Weaver

@ k11k2 ฉันคิดว่า "โมดูลการโหลดแบบขี้เกียจ" ของคุณไม่ได้ถูกโหลดอย่างเกียจคร้าน ตรวจสอบให้แน่ใจว่าคุณได้ใช้loadChildrenคุณสมบัติเป็นส่วนหนึ่งของเส้นทางไปยังโมดูลขี้เกียจของคุณ
hastrb

16

canActivateใช้เพื่อป้องกันผู้ใช้ที่ไม่ได้รับอนุญาต

canLoadใช้เพื่อป้องกันโมดูลทั้งหมดของแอพ

ตัวอย่างcanActivate :

{ path: 'product',canActivate:[RouteGaurd], component : ProductComponent }

ตัวอย่างcanLoad :

{ path: 'user' , canLoad: [AuthenticGuard], loadChildren : './user/user.module#UserModule' }

สำหรับผู้อ่านในอนาคต canActive เช่นไม่ขี้เกียจ แต่ canLoad คือ .. เนื่องจากมีloadChildren. ยิ่งไปกว่านั้นรุ่นล่าสุดของ angular คือ ..loadChildren: () => import('./user/user.module').then(m => m.UserModule)
hastrb

คำอธิบายง่ายๆชอบมาก :)
KTM

16

CanLoadยามป้องกันไม่ให้โหลดของโมดูลโหลดขี้เกียจ โดยทั่วไปเราใช้ตัวป้องกันนี้เมื่อเราไม่ต้องการให้ผู้ใช้ที่ไม่ได้รับอนุญาตนำทางไปยังเส้นทางใด ๆ ของโมดูลและหยุดจากนั้นดูซอร์สโค้ดของโมดูล

Angular มีcanActivate Guard ซึ่งป้องกันไม่ให้ผู้ใช้ที่ไม่ได้รับอนุญาตเข้าถึงเส้นทาง แต่ไม่ได้หยุดการดาวน์โหลดโมดูล ผู้ใช้สามารถใช้คอนโซลนักพัฒนาของ Chrome เพื่อดูซอร์สโค้ด CanLoad Guard ป้องกันไม่ให้ดาวน์โหลดโมดูล

อันที่จริงCanLoadป้องกันโมดูลที่จะโหลด แต่เมื่อโหลดโมดูลแล้วCanLoad guard จะไม่ทำอะไรเลย สมมติว่าเราได้ป้องกันการโหลดโมดูลโดยใช้CanLoad guard สำหรับผู้ใช้ที่ไม่ได้รับการพิสูจน์ตัวตน เมื่อผู้ใช้ล็อกอินแล้วโมดูลนั้นจะสามารถโหลดได้และเราจะสามารถนำทางพา ธ เด็กที่กำหนดค่าโดยโมดูลนั้นได้ แต่เมื่อผู้ใช้ออกจากระบบผู้ใช้ยังคงสามารถนำทางพา ธ เด็ก ๆ เหล่านั้นได้เนื่องจากโมดูลโหลดแล้ว ในกรณีนี้หากเราต้องการปกป้องเส้นทางเด็กจากผู้ใช้ที่ไม่ได้รับอนุญาตเราจำเป็นต้องใช้CanActivate guard ด้วย

ใช้CanLoadก่อนโหลด AdminModule:

  {
        path: 'admin',
        loadChildren: 'app/admin/admin.module#AdminModule',
        canLoad: [ AuthGuardService ]
      },

หลังจากโหลด AdminModule แล้วในโมดูล AdminRouting เราสามารถใช้CanActiveเพื่อปกป้องเด็กจากผู้ใช้ที่ไม่ได้รับอนุญาตเช่นร้อง:

{ 
      path: '',
      component: AdminComponent,
      children: [ 
        {
          path: 'person-list',
          component: PersonListComponent,
          canActivate: [ AuthGuardService ]
        }
      ]
    }  

ดังนั้นควรใช้ทั้ง canLoad และ canActivate?
Tarida George

0

canActivateหากผู้ใช้ที่ไม่ได้รับอนุญาตเข้าสู่ยังคงโหลดโมดูลนั้น คุณต้องcanLoadเพื่อให้เกิดการตัดสินว่าจำเป็นต้องโหลดหรือไม่


0

สิ่งสำคัญที่ต้องสังเกตว่าcanLoadจะไม่หยุดไม่ให้ใครบางคนรับซอร์สโค้ดของคุณ เบราว์เซอร์จะไม่ดาวน์โหลด. js เว้นแต่ว่าผู้ใช้จะได้รับอนุญาต แต่คุณสามารถบังคับให้ดาวน์โหลดด้วยตนเองได้โดยการสั่งนำเข้า ('./ xxxxx.js') บนคอนโซลเบราว์เซอร์

ชื่อโมดูลสามารถพบได้อย่างง่ายดายใน main.js ของคุณในนิยามเส้นทางของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.