У меня немного рассола.Я использую Route guard (реализующий интерфейс CanActivate
), чтобы проверить, предоставлен ли пользователю доступ к определенному маршруту:
const routes: Routes = [
{
path: '',
component: DashboardViewComponent
},
{
path: 'login',
component: LoginViewComponent
},
{
path: 'protected/foo',
component: FooViewComponent,
data: {allowAccessTo: ['Administrator']},
canActivate: [RouteGuard]
},
{
path: '**',
component: ErrorNotFoundViewComponent
}
];
Теперь он отлично работает для защиты маршрута / protected / foo от активации, ноЯ хотел бы сообщить пользователю, что маршрут, к которому он пытается получить доступ, запрещен (аналогично 403 Запрещено, вы можете получить с сервера).
Проблема: Как показать пользователю это специальное представление об ошибкене перенаправляя его на маршрут ошибки , какие швы являются предпочтительным вариантом для многих источников, которые я нашел? И как мне по-прежнему использовать мой RouteGuard
, фактически не загружая запрещенный маршрут, потому что, если я проверяю доступ внутри моего FooViewComponent
и отображаю другой вид, это как бы лишает смысла наличие RouteGuard
в первомplace.
В идеале я бы хотел, чтобы мой RouteGuard
не только возвращал false в методе canActivate()
, но и полностью заменял компонент, скажем, ErrorForbiddenViewComponent
.Но я понятия не имею, как это сделать, или это возможно событие.Любые альтернативы?
Вот так теперь выглядит мой охранник маршрута:
import {Injectable} from '@angular/core';
import {Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
import {AuthService} from '../services/auth.service';
@Injectable()
export class RouteGuard implements CanActivate {
constructor(
private router: Router,
private auth: AuthService
) {}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const { auth, router } = this;
const { allowAccessTo } = next.data;
const identity = auth.getIdentity();
if (
identity &&
allowAccessTo.indexOf(identity.role)
) {
// all good, proceed with activating route
return true;
}
if (identity) {
// TODO show ErrorForbiddenViewComponent instead of redirecting
console.log('403 Forbidden >>', next);
}
else {
// not logged in: redirect to login page with the return url
const [returnUrl, returnQueryParams] = state.url.split('?');
console.log('401 Unauthorised >>', returnUrl, returnQueryParams, next);
router.navigate(['/login'], {queryParams: {returnUrl, returnQueryParams}});
}
return false;
}
}
Так что я просто запрещаю загрузку маршрута, но не перенаправляю.Я только перенаправляю незарегистрированных посетителей на маршрут входа в систему.
Причина:
- Маршруты должны отражать определенное состояние приложения - посещение URL-адреса маршрута должно воссоздать это состояние
- Дляналичие маршрутов ошибок (за исключением 404 Not Found) означало бы, что ваше приложение может фактически воссоздавать состояния ошибок.Это не имеет никакого смысла, так как почему вы сохраняете состояние ошибки как состояние вашего приложения?Для целей отладки следует использовать журналы (консоль или сервер), повторное посещение страницы ошибок (т. Е. Обновление страницы) может помешать этому.
- Кроме того, путем перенаправления на маршрут ошибки приложение должно предоставить некоторую информацию об ошибке пользователю.В этом случае либо какой-либо параметр должен быть передан через url, либо (что намного хуже) сохранить состояние ошибки в некотором сервисе ошибок и получить его при доступе к маршруту ошибки.
- Кроме того, игнорирование RouteGuard и просто загрузка компонентаи проверка доступа внутри него может привести к загрузке некоторых дополнительных зависимостей, которые в любом случае не будут использоваться (так как пользователь не разрешен), значительно усложняет загрузку с отложенным доступом.
У кого-нибудь есть какое-то решениеза это?Мне также интересно, почему после того, как Angular 2+ так долго существовал, у кого-то такого раньше не было?Все в порядке с перенаправлением?
Также имейте в виду, что хотя в настоящее время я использую FooViewComponent
синхронно, это может измениться в будущем!