Angular 2 Служба аутентификации с перенаправлением?
У меня есть приложение, которое я создаю, которое реализует CanActivate на маршруте панели мониторинга. Он работает нормально, при перезагрузке страницы, я проверяю флажок в службе пользователя, чтобы увидеть, вошел ли пользователь в систему или нет. по умолчанию этот флаг имеет значение false, что вынуждает пользователя войти в систему. Также при перезагрузке страницы я пытаюсь получить данные об использовании с токеном в localStorage, если выборка прошла успешно, я хочу, чтобы они могли оставаться на панели инструментов. Проблема в том, что я вижу проблеск входа в систему и необходимость вручную перенаправить их на панель инструментов. Есть ли способ исправить это, когда authGuard ничего не делает, пока не проверит API? Код здесь: https://github.com/judsonmusic/tfl
Приборная панель:
import{ Component , ViewChild} from '@angular/core';
import {LoginComponent} from "../login.component";
import {UserService} from "../user.service";
import {SimpleChartComponent} from "../charts/simpleChart.component";
import {AppleChartComponent} from "../charts/appleChart.component";
import {BarChartComponent} from "../charts/barChart.component";
import {DonutChartComponent} from "../charts/donutChart.component";
import {AlertComponent} from 'ng2-bootstrap/ng2-bootstrap';
import {ModalDemoComponent} from "../modals/modalDemoComponent";
import {NgInitHelperComponent} from "../helpers/nginit.helper.component";
import {ModalDirective} from "ng2-bootstrap/ng2-bootstrap";
import {MODAL_DIRECTIVES, BS_VIEW_PROVIDERS} from 'ng2-bootstrap/ng2-bootstrap';
@Component({
selector: 'dashboard',
templateUrl: '/app/components/dashboard/dashboard.component.html',
providers: [UserService, BS_VIEW_PROVIDERS],
directives: [SimpleChartComponent, AppleChartComponent, BarChartComponent, DonutChartComponent, AlertComponent, ModalDemoComponent, NgInitHelperComponent, ModalDirective]
})
export class DashboardComponent {
public areas:any;
constructor() {
this.areas = [
"Spiritual",
"Habits",
"Relationships",
"Emotional",
"Eating Habits",
"Relaxation",
"Exercise",
"Medical",
"Financial",
"Play",
"Work/ Life Balance",
"Home Environment",
"Intellectual Well-being",
"Self Image",
"Work Satisfaction"
]
}
}
Маршруты:
import { Routes, RouterModule } from '@angular/router';
import { AboutComponent } from './components/about.component';
import {PageNotFoundComponent} from "./components/pageNotFound.component";
import {HomeComponent} from "./components/home.component";
import {DashboardComponent} from "./components/dashboard/dashboard.component";
import {SurveyComponent} from "./components/survey/survey.component";
import {ResourcesComponent} from "./components/resources.component";
import {LogoutComponent} from "./components/logout.component";
import {AuthGuard} from "./components/auth-guard.service";
import { loginRoutes, authProviders } from './login.routing';
import {LoginComponent} from "./components/login.component";
const appRoutes:Routes = [
{ path: '', component: HomeComponent },
{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
{ path: 'logout', component: LogoutComponent },
{ path: 'resources', component: ResourcesComponent },
{ path: 'survey', component: SurveyComponent },
{ path: 'about', component: AboutComponent},
{ path: 'login', component: LoginComponent},
{ path: '**', component: PageNotFoundComponent}
];
export const appRoutingProviders: any[] = [
authProviders
];
export const routing = RouterModule.forRoot(appRoutes);
вход в систему:
import { Routes } from '@angular/router';
import { AuthGuard } from './components/auth-guard.service';
import { AuthService } from './components/auth.service';
import { LoginComponent } from './components/login.component';
export const loginRoutes: Routes = [
{ path: 'login', component: LoginComponent }
];
export const authProviders = [
AuthGuard,
AuthService
];
Ответы
Ответ 1
in AuthGuard
Сделайте это
@Injectable()
export class AuthGuard implements CanActivate {
auth: any = {};
constructor(private authService: AuthService, private router: Router) {
}
canActivate() {
if (/*user is logged in*/) {
this.router.navigate(['/dashboard']);
return true;
}
else {
this.router.navigate(['/Login']);
}
return false;
}
}
Ответ 2
Я действительно изменил свой сервис на это, и он работает:
import { Injectable } from '@angular/core';
import { CanActivate, Router,
ActivatedRouteSnapshot,
RouterStateSnapshot } from '@angular/router';
import { AuthService } from './auth.service';
import {UserService} from "./user.service";
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router, private userService: UserService) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
if (this.authService.isLoggedIn){
console.log('ATUH GUARD SAYD THEY ARE ALREADY LOGGED IN!');
return true;
}else {
this.userService.getUser().subscribe((user) => {
console.log('AUTH GUARD GETTING USER', user);
if (user._id) {
this.authService.isLoggedIn = true;
// Store the attempted URL for redirecting
this.authService.redirectUrl = state.url;
this.router.navigate(['/dashboard']);
return true;
}else{
console.log('Validation Failed.');
localStorage.clear();
this.router.navigate(['/login']);
return false;
}
}, (error) => {
console.log('There was an error.');
this.router.navigate(['/login']);
return false
});
}
}
}
Ответ 3
Теперь вы можете вернуть UrlTree
из AuthGuard или логическое значение true/false.
https://blog.angularindepth.com/new-in-angular-v7-1-updates-to-the-router-fd67d526ad05
Вид поражен, никто еще не упомянул об этом! Извините, сейчас нет примера, но идея довольно проста.
Ответ 4
Вот как правильно обрабатывать перенаправления в защите с помощью UrlTree
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivateChild {
constructor(
private authService: AuthService,
private logger: NGXLogger,
private router: Router
) {}
canActivateChild(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> {
return this.authService.isLoggedIn().pipe(
map(isLoggedIn => {
if (!isLoggedIn) {
return this.router.parseUrl('/login');
}
return true;
})
);
}
}
Большое спасибо Angular In Depth за объяснение!