因此,我试图为我的Web应用程序实现Route Guards,但遇到了很多错误。我做错了什么?
我的Web应用程序由多个路由组成,其中之一是仪表板,该仪表板需要由登录组件保护。那正是我尝试实现的,但是失败了。我的登录组件从后端生成JWT令牌,并将其添加到LocalStorage(格式为“令牌”:““)。
我的dashboard.component.ts:
import { Component, OnInit } from '@angular/core';
import { User } from '../models/user.model';
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
user: User;
constructor() { }
ngOnInit() {
}
canDeactivate(): Promise<any> | boolean {
if (localStorage.getItem('currentUserToken') === 'token') {
return (true);
} else {
return (false);
}
}
}
我的auth.guard.ts:
import {Injectable} from '@angular/core';
import {ActivatedRoute, ActivatedRouteSnapshot, CanActivate, CanLoad, Route, Router, RouterStateSnapshot} from '@angular/router';
@Injectable()
export class AuthGuard implements CanActivate, CanLoad {
constructor(private router: Router) {
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
return this.checkToken();
}
canLoad(route: Route): boolean {
return this.checkToken();
}
checkToken() {
if (localStorage.getItem('currentUserToken')) {
return true;
} else {
this.router.navigateByUrl('/avior/login');
return false;
}
}
}
我的can-exit.guard.ts:
import {Injectable} from '@angular/core';
import {CanDeactivate} from '@angular/router';
import {CanExit} from './canExit';
@Injectable()
export class CanExitGuard implements CanDeactivate<CanExit> {
canDeactivate(component: CanExit) {
if (component.canDeactivate) {
return component.canDeactivate();
}
return true;
}
}
我的canExit.ts:
import {Observable} from 'rxjs';
export interface CanExit {
canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;
}
浏览器中的错误是:
DashboardComponent.ngfactory.js? [sm]:1 ERROR TypeError: Cannot read property 'id' of undefined
DashboardComponent.ngfactory.js? [sm]:1 ERROR CONTEXT DebugContext_ {view: {…}, nodeIndex: 1, nodeDef: {…}, elDef: {…}, elView: {…}}
ERROR TypeError: Cannot read property 'id' of undefined
ERROR CONTEXT DebugContext_ {view: {…}, nodeIndex: 1, nodeDef: {…}, elDef: {…}, elView: {…}}
更新: StackBlitz: https://stackblitz.com/edit/angular-v9u7nw?file=src%2Fapp%2Fapp.routing.ts
答案 0 :(得分:1)
要重定向用户到登录组件,您需要在定义的路由路径中使用路由器防护。我在这里没有为此用例设置令牌部分。您可以找到完整的StackBlitz Link here作品。如果您直接重定向到/ dashboard,则在用户尚未登录时auth-guard重定向到/ login。
您的auth-guard是..
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean> | Promise<boolean> | boolean {
if(this.authService.isUserLoggedIn()){
return true;
}else{
this.router.navigate(['/login'],{relativeTo: this.activatedRouter});
return false;
}
}
您的身份验证服务如下所示。
isAuthenticated(username: string, password: string): Observable <boolean>{
return this.getAllUsers().pipe(
map(users => {
let user = users.find( user => (user.username === username) && (user.password === password) );
console.log(user)
if (user) {
this.isLoggedin = true;
this.loggedInUser = user;
} else {
this.isLoggedin = false;
}
return this.isLoggedin;
})
)
}
您的应用程序路由模块是..
const routes: Routes = [{path: 'login', component: LoginComponent},
{path: '', redirectTo: 'login', pathMatch: 'full'},
{path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard]}
];
您的登录提交方法。
this.authService.isAuthenticated(this.loginForm.get('username').value,this.loginForm.get('password').value).subscribe(authenticated =>{
if (authenticated){
let url = this.authService.getRedirectUrl();
this.router.navigate([url]);
}
});