我创建了此authguard,但在用户注销时没有阻止该路由。 app auth工作流程正常,我在后端使用db上的传统会话,我使用Augury扩展验证了使用chrome的auth服务的状态,并且auth状态设置为ok,具有不同的操作,因此问题不存在。
这是我的 auth-guard.service.ts 服务:
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { AuthService } from './auth.service';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router){}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
return this.authService.isAuthenticated().map(isAuth => {
console.log('is authenticated',isAuth);
if (isAuth) {
return true;
}else{
this.router.navigate(['/signin']);
return Observable.of(false);
}
}).catch(() => {
return Observable.of(false);
});;
}
}
这是我的 authService ,其方法是isAuthenticated(),由auth guard用来阻止或不阻止路由(我使用publishReplay来捕获authState 5次以保存由于我没有找到更好的方法来检查用户身份验证状态,因此我只是进行查询,并且如果后端的auth后卫不拒绝它,那么这意味着会话仍然是主动返回代码200:
import { Injectable, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Http, Response, RequestOptions, Headers } from '@angular/http';
import 'rxjs/add/operator/map';
import {Observable, Subject} from "rxjs/Rx";
@Injectable()
export class AuthService implements OnInit {
userIsAuthenticated = new Subject();
constructor(private router: Router, private http: Http) { }
private getHeaders(){
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');
headers.append('Authorization','Bearer');
return headers;
}
ngOnInit(){
//it starts as false to check with the server if the user is authenticated
this.userIsAuthenticated.next(false);
}
isAuthenticated(): Observable<boolean> {
let options = new RequestOptions({ headers: this.getHeaders(), withCredentials: true });
return this.http.get('http://someurl/api/sponsor/check/login',options)
.map(response => {
let res = response.json();
console.log("response");
if (res.code == 200) {
this.userIsAuthenticated.next(true);
return true;
} else {
this.userIsAuthenticated.next(false);
return false;
}
}
).publishReplay(5);
}
}
这是我的路由文件:
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AuthGuard } from './auth/auth-guard.service';
import { SigninComponent } from './auth/signin/signin.component';
import { SignupComponent } from './auth/signup/signup.component';
import { MainComponent } from './main/main.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { ActiveCampaignsComponent } from './dashboard/active-campaigns/active-campaigns.component';
import { HistoryCampaignsComponent } from './dashboard/history-campaigns/history-campaigns.component';
import { OverviewCampaignsComponent } from './dashboard/overview-campaigns/overview-campaigns.component';
const appRoutes: Routes = [
{ path: '', redirectTo: '/', pathMatch:'full'},
{ path: '', component: MainComponent },
{ path: 'signin', component:SigninComponent},
{ path: 'signup', component: SignupComponent},
{ path: 'dashboard', canActivate:[AuthGuard],component: DashboardComponent,
children: [
{ path: '', redirectTo:'dashboard/overview', pathMatch: 'full'},
{ path: 'overview', component: OverviewCampaignsComponent },
{ path: 'active', component: ActiveCampaignsComponent},
{ path: 'history', component: HistoryCampaignsComponent}
] }
]
@NgModule({
imports: [RouterModule.forRoot(appRoutes)],
exports: [RouterModule]
})
export class AppRoutingModule{
}
正如您所看到的那样,仪表板路由正在实施此版权保护,但它没有阻止任何内容,如果我添加该行,它会阻止所有链接的意外行为(这种情况我会注销并尝试通过网址访问到仪表板路线,它打破了应用程序,但在控制台中没有看到错误,链接在做完之后没有响应)。什么似乎是问题?谢谢!
答案 0 :(得分:1)
我认为您忘记了在AppModule
的Providers数组中添加防护,也在组件名称后添加了canActivate
,上面应该有类似的代码。(这可能就是为什么Guard不提供的原因保护仪表板路线。
@NgModule({
imports: [
RouterModule.forRoot([
{
path: 'dashboard',
component: DashboardComponent,
canActivate:[AuthGuard],
}
])
],
providers: [AuthGuard]
})
class AppModule {}
答案 1 :(得分:0)
问题是我没有在map之后的isAuthenticated方法上捕获authService上的错误,所以authGuard代码由于在给它机会执行之前抛出错误而没有执行,我删除了publishReplay(用于缓存)以及导致代码在输入受保护的URL后没有执行,但我更愿意打开另一个有问题的主题。谢谢:
<强> authService 强>:
isAuthenticated(): Observable<boolean> {
let options = new RequestOptions({ headers: this.getHeaders(), withCredentials: true });
return this.http.get('http://localhost:3000/api/check/login',options)
.map(response => {
let res = response.json();
console.log("response");
if (res.code == 200) {
this.userIsAuthenticated.next(true);
return true;
}
}
).catch((err)=>{
//maybe add in the future if the code is 403 then send him to login otherwise send him elsewhere
return Observable.of(false);
});
}
authGuard,我在没有从Observable.of(false)登录的情况下更改了返回值,只是假(我不认为这是强制性的,因为签名允许你返回一个Observable,但我只是我希望详细说明问题的解决方案:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
return this.authService.isAuthenticated().map(isAuth => {
console.log('is authenticated',isAuth);
if (isAuth) {
return true;
}else{
this.router.navigate(['/signin']);
return false;
}
});
}
与我之前发布的内容相比,路线文件没有变化。