我试图通过仅允许某些ID进行访问来确保前端的安全。我希望,如果有人尝试输入除/ login /:id以外的任何路由,如果他尚未登录,则将无法找到页面,但无法正常工作。 这些是我的路由表和防护:
编辑: 我解决了问题并更新了代码
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();
}
答案 0 :(得分:3)
所以我设法解决了这个问题。 我添加了login /:id children:[]的路由,并将isLoggedIn更改为behaviorSubject,因此令牌在刷新或在页面之间移动后不会更改,并且可以正常工作。我更新了帖子中的代码,以便每个人都可以看到解决方案
答案 1 :(得分:2)
更改此行:
const id = route.params.id;
到
const id = +route.params.id; // to convert from string to number (it's string from route params)
还有一件事,我不确定您是否应该像[[**]]一样导航到未找到的页面
执行以下操作:['/ page_not_found']
现在我知道您的路线中不存在“ page_not_found”,但这就是重点, 因此,该用户将被重定向到您想要的页面