Возможно, я немного не согласен с тем, что здесь происходит, из-за того, как глубоко в Angular гнездятся наблюдатели, и из-за трудностей, возникающих при отладке подобных вещей, но я наблюдаю именно это.
У меня есть приложение Angular 5, использующее @ angular / router 5.2.6, у меня есть служба Guard, у меня есть внешняя служба аутентификации пользователя типа SSO. Если пользователь не аутентифицирован, мне нужно иметь возможность перенаправить его в службу аутентификации, войти в систему, если требуется, и вернуться к тому же URL-адресу, который он первоначально пытался получить.
Итак, у меня настроены маршруты, и в качестве условия canActivate маршрута используется служба Guard Я использую
window.location.href = "...";
для перенаправления из моего приложения в сервис авторизации. А также верните false из метода canActivate после установки этого перенаправления.
Моя служба аутентификации зависит от заголовка Referrer, который должен знать, куда отправить пользователя обратно с токеном после проверки подлинности. Это прекрасно работает в большинстве браузеров, но в Chrome браузер позволяет развернуть весь стек событий перед перенаправлением.
То есть, что, по-видимому, происходит:
window.location.href = "...";
- canActivate возвращает false.
- Поскольку маршрут не может активироваться, пользователь сбрасывается в корень приложения.
- Через долю секунды происходит перенаправление.
Однако, поскольку мы впервые попали в корень приложения, заголовок Referrer неправильный.
Так, каковы мои варианты здесь?
- Если я верну true вместо false, перенаправление произойдет с
правильный заголовок, но это не самая безопасная вещь.
- Если я использую параметр запроса с исходным URL-адресом, мне понадобится посредник между моим приложением и службой аутентификации, чтобы перевести его обратно в заголовок Referrer.
- Вместо расположения окна я могу создать тег Anchor с URL-адресом службы аутентификации и программно щелкнуть по нему. Похоже, это приводит к короткому замыканию маршрутизатора и предотвращает полное развертывание canActivate.
Что еще я могу сделать? Может быть, какое-то наблюдаемое возвращение, ожидающее popstate или hashchange и возвращающее URL? Есть ли что-то, чего я не вижу, как вы думаете, у меня даже проблема исправлена?
РЕДАКТИРОВАТЬ: Добавление методов canActivate
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
const url: string = state.url;
if (this.authService.config.permissionsEndpointUrl && this.authService.config.hasUserPermissions) {
// If permissions are configured, check both the user session token and user access permissions
return this.checkLogin(url) && this.checkPermissions(route.data['permissions']);
} else {
// Otherwise, only check the user session token
return this.checkLogin(url);
}
}
private checkLogin(url: string): boolean {
const currentUser = this.authService.getUserSessionDetails();
if (currentUser && currentUser.token && this.authService.tokenNotExpired(currentUser.token)) {
return true;
}
// Store the attempted URL for redirecting after login
this.authService.redirectUrl = url;
this.authService.redirectToLogin(true);
return false;
}
redirectToLogin(guardMode: boolean = false): void {
...
if (this.config.loginRoutePath) {
window.location.href = this.config.loginRoutePath;
}
...
}