Angular 守卫 canActivate 方法不适用于 Observable<boolean>
Angular guard canActivate method dont work with Observable<boolean>
我正在尝试在访问路由之前在后端验证令牌
这是我的身份验证服务:
export class AuthService {
private registerUrl = 'http://127.0.0.1:3000/register';
private loginUrl = 'http://127.0.0.1:3000/signin';
private verifyTokenUrl = 'http://127.0.0.1:3000/v';
constructor(private http: HttpClient) { }
isLoggedIn() {
if (!localStorage.getItem('token')) {
console.log('false in isloggedin method');
return false;
}
console.log('logged in, not verified yet');
return true;
}
isTokenValid(token): Observable<boolean> {
console.log('verifing');
return this.http.post<any>(this.verifyTokenUrl, {token});
}
getToken() {
return localStorage.getItem('token');
}
}
后卫:
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService,
private router: Router) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
if (this.authService.isLoggedIn()) {
const token = localStorage.getItem('token');
this.authService.isTokenValid(token)
.pipe(
map(e => {
if (e) {
return true;
} else {
this.router.navigate(['/login']);
return false;
}
}),
catchError((err) => {
this.router.navigate(['/login']);
return of(false);
})
);
} else {
this.router.navigate(['/login']);
return of(false);
}
}
}
似乎 observable 没有激活 "like when you use the subscribe method" 而 API 中的代码甚至没有 运行。 canActivate() 假设接受一个 Observable 作为返回值。守卫将等待 Observable 解析并查看值。如果 'true' 它将通过检查,否则(任何其他数据或抛出的错误)将拒绝路由。参考这个
在我的例子中,应用程序停留在当前页面,不会路由到目标,也不会 post 到服务器。还有一个类似的问题here,他们通过添加.take(1)
解决了这个问题,但在我的例子中它给出了一个错误Property 'take' does not exist on type 'OperatorFunction<{}, boolean>'
这是我的验证码 API 以防万一
//.........token verify
app.post('/v', (req, res) => {
const {token} = req.body
const payload = jwt.verify(token, 'secretKey' )
console.log(payload);
if (!payload) {
return res.status(401).send(false)
}
res.status(200).send(true)
})
您没有返回您的可观察对象:
this.authService.isTokenValid(token)
//...
—>
return this.authService.isTokenValid(token)
//...
尝试实现你的路由守卫返回一个 observable:
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService,
private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return Observable.create(observer => {
if (this.authService.isLoggedIn()) {
const token = localStorage.getItem('token');
this.authService.isTokenValid(token)
.pipe(
map(e => {
if (e) {
observer.next(true);
} else {
this.router.navigate(['/login']);
observer.next(false);
}
}),
catchError((err) => {
this.router.navigate(['/login']);
observer.next(false);
})
);
} else {
this.router.navigate(['/login']);
observer.next(false);
}
});
}
}
此外,不要忘记在 app.module:
中将拦截器实现为提供者
// your.module.ts
// ...
providers: [
...,
AuthGuard
];
还有你要守护的路线:
// some route to guard
{ path: 'guarded-route', component: GuardedRouteComponent, canActivate: [AuthGuard] }
我正在尝试在访问路由之前在后端验证令牌
这是我的身份验证服务:
export class AuthService {
private registerUrl = 'http://127.0.0.1:3000/register';
private loginUrl = 'http://127.0.0.1:3000/signin';
private verifyTokenUrl = 'http://127.0.0.1:3000/v';
constructor(private http: HttpClient) { }
isLoggedIn() {
if (!localStorage.getItem('token')) {
console.log('false in isloggedin method');
return false;
}
console.log('logged in, not verified yet');
return true;
}
isTokenValid(token): Observable<boolean> {
console.log('verifing');
return this.http.post<any>(this.verifyTokenUrl, {token});
}
getToken() {
return localStorage.getItem('token');
}
}
后卫:
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService,
private router: Router) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
if (this.authService.isLoggedIn()) {
const token = localStorage.getItem('token');
this.authService.isTokenValid(token)
.pipe(
map(e => {
if (e) {
return true;
} else {
this.router.navigate(['/login']);
return false;
}
}),
catchError((err) => {
this.router.navigate(['/login']);
return of(false);
})
);
} else {
this.router.navigate(['/login']);
return of(false);
}
}
}
似乎 observable 没有激活 "like when you use the subscribe method" 而 API 中的代码甚至没有 运行。 canActivate() 假设接受一个 Observable 作为返回值。守卫将等待 Observable 解析并查看值。如果 'true' 它将通过检查,否则(任何其他数据或抛出的错误)将拒绝路由。参考这个
在我的例子中,应用程序停留在当前页面,不会路由到目标,也不会 post 到服务器。还有一个类似的问题here,他们通过添加.take(1)
解决了这个问题,但在我的例子中它给出了一个错误Property 'take' does not exist on type 'OperatorFunction<{}, boolean>'
这是我的验证码 API 以防万一
//.........token verify
app.post('/v', (req, res) => {
const {token} = req.body
const payload = jwt.verify(token, 'secretKey' )
console.log(payload);
if (!payload) {
return res.status(401).send(false)
}
res.status(200).send(true)
})
您没有返回您的可观察对象:
this.authService.isTokenValid(token)
//...
—>
return this.authService.isTokenValid(token)
//...
尝试实现你的路由守卫返回一个 observable:
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService,
private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return Observable.create(observer => {
if (this.authService.isLoggedIn()) {
const token = localStorage.getItem('token');
this.authService.isTokenValid(token)
.pipe(
map(e => {
if (e) {
observer.next(true);
} else {
this.router.navigate(['/login']);
observer.next(false);
}
}),
catchError((err) => {
this.router.navigate(['/login']);
observer.next(false);
})
);
} else {
this.router.navigate(['/login']);
observer.next(false);
}
});
}
}
此外,不要忘记在 app.module:
中将拦截器实现为提供者// your.module.ts
// ...
providers: [
...,
AuthGuard
];
还有你要守护的路线:
// some route to guard
{ path: 'guarded-route', component: GuardedRouteComponent, canActivate: [AuthGuard] }