使用 MEAN 堆栈验证持有者令牌 API
Verify bearer token API with the MEAN stack
我正在开发 angular 应用程序,但我很难实现 api 的不记名令牌验证。
过程如下所示:
- Authguard 要求 AuthService 验证本地存储的身份验证令牌
canActivate(): boolean {
if(this.AuthService.isAuthenticated()){
return true;
} else{
this.router.navigate(['elsewhere/maybeToSwimmingPool']);
}
}
- AuthService 调用 isAuthenticated 方法,如果令牌有效,该方法将从 api
获取
isAuthenticated(){
if(localStorage.getItem('token')){
this.verifyToken().subscribe(
data => {return data;}
)
}else{
return false;
}
}
verifyToken() : Observable<boolean>{
const url = this.apiVerifyTokenUrl + '/' + localStorage.getItem('token');
return this.http.get<boolean>(apiVerifyTokenUrl, this.httpOptions);
}
- Api 解码令牌,检查用户是否存在于数据库中,return 布尔值
exports.verifyToken = (req, res, next) => {
try{
verifiedJwt = jwt.verify(req.params.token, secret);
let userId= verifiedJwt.userId;
User.findOne({_id: userId})
.then(() => res.status(200).send('true'))
.catch(error => res.status(200).send('false'));
}
catch(e){
res.status(200).send('false');
}
}
我不确定我编写的是什么怪物。也许 Authguard 不能异步等待 observable?
我真的不知道我的代码有什么问题,我希望你们能找到致命的错误并给我建议我的代码?这些是我在 mean stack 上的第一步,我欢迎每一个建议,批评 :)
祝你有美好的一天,
埃尔克·约翰逊
您正在 CanActivate 守卫中使用异步代码,因此您不应该 return boolean
,而是 return Observable<boolean>
。同样,您的 isAuthenticated 方法不应调用 subscribe
,而应调用 return 一个可观察对象。您的代码不起作用的原因是 Guard 不会等待所有订阅块完成。相反,Guard 会立即 return 一些值(同步地)并且您的令牌检查会在稍后发生。
我想如果你这样构建它会起作用。我没有碰你的后端。
- 在守卫中 return 结果的可观察性,如果用户未通过身份验证,则在
tap
运算符中产生副作用。守卫将订阅 canActivate
函数的 return 值。
canActivate(): Observable<boolean> {
return this.AuthService.isAuthenticated().pipe(
tap( isAuthenticated => !isAuthenticated ? this.router.navigate(['elsewhere/maybeToSwimmingPool']): 0)
);
这里不是订阅,你只是 return 一个可观察的。
isAuthenticated(): Obsevable<boolean>{
const token = localStorage.getItem('token');
if(token){
return this.verifyToken(token)
}
}
verifyToken(token) : Observable<boolean>{
const url = this.apiVerifyTokenUrl + '/' + token
return this.http.get<boolean>(apiVerifyTokenUrl, this.httpOptions);
}
我正在开发 angular 应用程序,但我很难实现 api 的不记名令牌验证。
过程如下所示:
- Authguard 要求 AuthService 验证本地存储的身份验证令牌
canActivate(): boolean {
if(this.AuthService.isAuthenticated()){
return true;
} else{
this.router.navigate(['elsewhere/maybeToSwimmingPool']);
}
}
- AuthService 调用 isAuthenticated 方法,如果令牌有效,该方法将从 api 获取
isAuthenticated(){
if(localStorage.getItem('token')){
this.verifyToken().subscribe(
data => {return data;}
)
}else{
return false;
}
}
verifyToken() : Observable<boolean>{
const url = this.apiVerifyTokenUrl + '/' + localStorage.getItem('token');
return this.http.get<boolean>(apiVerifyTokenUrl, this.httpOptions);
}
- Api 解码令牌,检查用户是否存在于数据库中,return 布尔值
exports.verifyToken = (req, res, next) => {
try{
verifiedJwt = jwt.verify(req.params.token, secret);
let userId= verifiedJwt.userId;
User.findOne({_id: userId})
.then(() => res.status(200).send('true'))
.catch(error => res.status(200).send('false'));
}
catch(e){
res.status(200).send('false');
}
}
我不确定我编写的是什么怪物。也许 Authguard 不能异步等待 observable? 我真的不知道我的代码有什么问题,我希望你们能找到致命的错误并给我建议我的代码?这些是我在 mean stack 上的第一步,我欢迎每一个建议,批评 :)
祝你有美好的一天, 埃尔克·约翰逊
您正在 CanActivate 守卫中使用异步代码,因此您不应该 return boolean
,而是 return Observable<boolean>
。同样,您的 isAuthenticated 方法不应调用 subscribe
,而应调用 return 一个可观察对象。您的代码不起作用的原因是 Guard 不会等待所有订阅块完成。相反,Guard 会立即 return 一些值(同步地)并且您的令牌检查会在稍后发生。
我想如果你这样构建它会起作用。我没有碰你的后端。
- 在守卫中 return 结果的可观察性,如果用户未通过身份验证,则在
tap
运算符中产生副作用。守卫将订阅canActivate
函数的 return 值。
canActivate(): Observable<boolean> {
return this.AuthService.isAuthenticated().pipe(
tap( isAuthenticated => !isAuthenticated ? this.router.navigate(['elsewhere/maybeToSwimmingPool']): 0)
);
这里不是订阅,你只是 return 一个可观察的。
isAuthenticated(): Obsevable<boolean>{
const token = localStorage.getItem('token');
if(token){
return this.verifyToken(token)
}
}
verifyToken(token) : Observable<boolean>{
const url = this.apiVerifyTokenUrl + '/' + token
return this.http.get<boolean>(apiVerifyTokenUrl, this.httpOptions);
}