Різниця між CanLoad і CanActivate від Angular?


101

У чому різниця між 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;
}

Коли я, хто з них?

Відповіді:


100

canActivate використовується для запобігання доступу несанкціонованих користувачів до певних маршрутів. Для отримання додаткової інформації дивіться документи .

canLoad використовується для запобігання застосунку лінивого завантаження цілих модулів, якщо користувач не має на це дозволу.

Для отримання додаткової інформації дивіться документи та приклад нижче.

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

За допомогою цього коду код для AdminModule буде завантажений у програму, лише якщо AuthGuard повернеться true.

Якщо користувач не має дозволу на доступ до цього маршруту, і ми використовували лише canActivateохорону, AdminModuleвін буде завантажений, навіть якщо користувач не зможе отримати доступ до цього маршруту.


6
Якщо я застосую canActivateв наведеному вище сценарії, яка буде різниця?
k11k2

3
canActiveБуде завантажено @ k11k2 з модулем (F12> Джерела - в хромі). Ви можете побачити там файли .js. З canLoadцими модулями (файли .js) не завантажуватимуться :) Перевірте мою відповідь вище, де я це пояснив краще
DiPix 13.03.18

23
Що стосується сценарію, коли адміністратор ввійшов у систему, тож модуль адміністратора завантажився через canLoadповертає true, а потім вийшов із програми. Тепер користувач, що не є адміністратором, входить в той самий браузер, як це працює? Чи виселений або видалений із кеш-пам'яті завантажений модуль?
Keerthivasan

2
@Keerthivasan нічого не змушує видалити раніше завантажений шматок ледачого AdminModule, коли користувач вийшов із системи та ввійшов знову за допомогою іншого облікового запису, який не має достатнього дозволу для завантаження AdminModule. Однак ви все одно не отримаєте доступу .. крім наявності завантаженого кешованого модуля. Я не думаю, що це справжня проблема безпеки, оскільки зазвичай один пристрій - це один реальний користувач
hastrb

1
@ sgClaudia98 ви можете використовувати обидва, але існує суворий порядок виконання охорони. ось чому у вашій справі немає ніякої різниці щодо того, що я трохи раніше заявляв. Думаю, у своєму першому коментарі я дав дуже детальне пояснення. Це було б досить дивним випадком, якщо на сьогоднішній день існує один пристрій, а адміністратор / не адміністратор входять один за одним.
hastrb

36
  • CanActivate - вирішує, чи можна активувати маршрут, цей захист може бути не найкращим способом для функціональних модулів, які ледаче завантажуються, оскільки цей захист завжди завантажує модуль у пам'ять, навіть якщо захисник повертає false, тобто користувач не має права доступу маршрут.
  • CanLoad - вирішує, чи можна модуль ліниво завантажувати, контролює, чи можна маршрут навіть завантажити. Це стає корисним для функціональних модулів, які ледаче завантажуються. Вони навіть не завантажаться, якщо охоронець поверне помилку.

Це тест, який я зробив на обох охоронцях із модулем функцій, який ледаче завантажується:

1. CanActivate Guard Test

Ви помітите внизу Мережевої сторінки, що він зробив 24 запити розміром 9,5 МБ, передану обробку за 3,44 секунди та повністю завантажену за 3,47 секунди.

Тест CanActivate Guard на модулі функцій лінивого завантаження

1. Тест CanLoad Guard

тут ви побачите велику різницю, коли ми використовували CanLoad Guard, оскільки браузер робив лише 18 запитів розміром 9,2 МБ, передані обробки за 2,64 секунди та повністю завантажених 2,59 секунди.

Тест CanLoad Guard на модулі функцій лінивого завантаження

CanLoad Guard ніколи не завантажує дані модуля, якщо користувач не авторизований, і це дає вам більшу продуктивність, оскільки час завантаження зменшився майже на 1 секунду, і це величезний час при завантаженні веб-сторінок, без сумніву, це залежить від розміру модуля.

Порада: якщо ви хочете зробити тест на своєму проекті, переконайтеся, що Disable Cacheпрапорець на вкладці мережі встановлений, це позначено на першому зображенні


3
Тільки щоб когось не заплутати .. 403 - це Заборонено, а не Несанкціоноване - 401.
hastrb

20

Щодо запитання з коментарів в іншому дописі: "Якщо я використовую canActivate у наведеному вище сценарії, яка різниця буде?"

Насправді для користувача різниці не буде, він не отримає доступу до сторінки в обох випадках. Хоча є одна прихована різниця . Якщо натиснути F12 і перейти до джерел (у Chrome), де знаходяться файли для завантаження. Тоді ви бачите, що у випадку з canActive завантажено файл із кодом ( chunk.js ). Навіть якщо у вас немає доступу до сторінки. введіть тут опис зображення

Але у випадку з canLoad не буде файлу chunk.js із вихідним кодом.

введіть тут опис зображення

Отже, як ви бачите, це має справді великий вплив на безпеку.

І звичайно, не забувайте, що canLoad можна використовувати лише для модулів LazyLoaded .


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. Більше того, остання версія loadChildren: () => import('./user/user.module').then(m => m.UserModule)
angular

Дуже просте пояснення, сподобалось :)
KTM

16

CanLoad Guard запобігає завантаженню завантаженого модуля ледачих. Зазвичай ми використовуємо цей захист, коли не хочемо, щоб несанкціонований користувач переходив до будь-якого з маршрутів модуля, а також зупинявся, а потім навіть бачив вихідний код модуля.

Angular надає функцію canActivate Guard, яка запобігає доступу неавторизованого користувача до маршруту. Але це не зупиняє завантаження модуля. Користувач може використовувати консоль розробника chrome, щоб переглянути вихідний код. CanLoad Guard запобігає завантаженню модуля.

Насправді CanLoad захищає модуль, який потрібно завантажити, але як тільки модуль завантажується, то захисник CanLoad нічого не зробить. Припустимо, ми захистили завантаження модуля за допомогою захисту CanLoad для неавторизованого користувача. Коли користувач увійде в систему, тоді цей модуль буде застосовним для завантаження, і ми зможемо орієнтуватися у дочірніх шляхах, налаштованих цим модулем. Але коли користувач виходить із системи, користувач все ще зможе орієнтуватися в цих дочірніх шляхах, оскільки модуль уже завантажений. У цьому випадку, якщо ми хочемо захистити дитячі шляхи від несанкціонованих користувачів, нам також потрібно використовувати захист CanActivate .

Використовуйте 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?
Таріда Джордж

0

canActivate, якщо неавторизований користувач все ще завантажує цей модуль. вам потрібно canLoad, щоб досягти судження про те, чи потрібно його завантажувати.


0

Важливо зауважити, що canLoad не завадить комусь отримати ваш вихідний код. .Js не буде завантажуватися браузером, якщо користувач не буде авторизований, але ви можете змусити завантажити вручну, здійснивши імпорт ('./ xxxxx.js') на консолі браузера.

Ім'я модуля можна легко знайти на вашому main.js у визначенні маршрутів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.