typescript - Angular 6: Vakt på alla rutter fungerar inte
Jag försöker göra frontend säkrad genom att endast låta vissa ID:n få tillgång. Jag vill att om någon försöker gå in på någon rutt förutom /login/:id, ska han få sidan-finns-inte om han inte redan har loggat in, men det fungerar inte.
Detta är min routningstabell och vakt:
REDIGERA: Jag löste problemet och uppdaterade koden:
app-routing.module.ts
// Routing array - set routes to each html page
const appRoutes: Routes = [{
path: 'login/:id',
canActivate: [AuthGuard],
children: []
},
{
path: '',
canActivate: [AuthGuard],
canActivateChild: [AuthGuard],
children: [{
path: '',
redirectTo: '/courses',
pathMatch: 'full'
},
{
path: 'courses',
component: CourseListComponent,
pathMatch: 'full'
},
{
path: 'courses/:courseId',
component: CourseDetailComponent,
pathMatch: 'full'
},
{
path: 'courses/:courseId/unit/:unitId',
component: CoursePlayComponent,
children: [{
path: '',
component: CourseListComponent
},
{
path: 'lesson/:lessonId',
component: CourseLessonComponent,
data: {
type: 'lesson'
}
},
{
path: 'quiz/:quizId',
component: CourseQuizComponent,
data: {
type: 'quiz'
}
}
]
}
]
},
{
path: '**',
component: PageNotFoundComponent,
pathMatch: 'full'
}
];auth.guard.ts
canActivate(route: ActivatedRouteSnapshot, state:
RouterStateSnapshot): boolean |
Observable<boolean> | Promise<boolean> {
// save the id from route snapshot
const id = +route.params.id;
// if you try to logging with id
if (id) {
this.authUserService.login(id);
// if there was error - return false
if (this.authUserService.errorMessage) {
this.router.navigate(["/page_not_found"]);
return false;
}
// there wasn't any errors - redirectTo courses and
// continue
else {
this.router.navigate(["courses"]);
return true;
}
}
// if you already logged and just navigate between pages
else if (this.authUserService.isLoggedIn())
return true;
else {
this.router.navigate(["/page_not_found"]);
return false;
}
}
canActivateChild(route: ActivatedRouteSnapshot, state:
RouterStateSnapshot): boolean |
Observable<boolean> | Promise<boolean> {
return this.canActivate(route, state);
}auth-user.service.ts
export class AuthUserService implements OnDestroy {
private user: IUser;
public errorMessage: string;
isLoginSubject = new BehaviorSubject<boolean>(this.hasToken());
constructor(private userService: UserService) {}
// store the session and call http get
login(id: number) {
this.userService.getUser(id).subscribe(
user => {
this.user = user;
localStorage.setItem('user', JSON.stringify(this.user));
localStorage.setItem('token', 'JWT');
this.isLoginSubject.next(true);
},
error => this.errorMessage = <any>error
);
}
// if we have token the user is loggedIn
// @returns {boolean}
private hasToken(): boolean {
return !!localStorage.getItem('token');
}
// @returns {Observable<T>}
isLoggedIn(): Observable<boolean> {
return this.isLoginSubject.asObservable();
}
// clear sessions when closing the window
logout() {
localStorage.removeItem('user');
localStorage.removeItem('token');
this.isLoginSubject.next(false);
}
ngOnDestroy() {
this.logout();
}Svar #1
Så jag lyckades lösa detta problem. Jag lade till children: [] till routen login/:id och ändrade isLoggedIn till att vara behaviorSubject så att token inte skulle ändras efter uppdatering eller när man navigerar mellan sidor, och det fungerade. Jag uppdaterade koden i inlägget så att alla kunde se lösningen
Svar #2
ändra denna rad:
const id = route.params.id;
till
const id = +route.params.id; // to convert from string to number (it's string from route params)
och en sak till, jag är inte säker på att du borde navigera till en sida som inte finns som du gjorde ['**']
istället gör detta: ['/page_not_found']
nu vet jag att 'page_not_found' inte finns i din rutt men det är poängen, på grund av det kommer användaren att omdirigeras till en sida som inte finns som du ville
