您好。我试图为我的angular 2.2.0应用程序实现路由保护时遇到问题。
我已经使用http get请求实现了一个简单的身份验证验证,虽然当我导航到应用程序本身的受保护路由时它完美运行,但当我通过Url访问相同路由时它会失败。
我有一个到配置文件的路由,记录的用户可以访问该路由,未记录的用户将被重定向到路由/login
当我通过以下方法访问路线时:
// Acessing the route by using Angular's navigate function:
<div [routerLink]="['profile']"> Profile </div>
// or
// html
<div (click)="goToProfile()"> Profile </div>
// ts
click(){
this._router.navigate(["profile"]);
}
完美无缺。记录的用户通常会访问/profile
路由,未记录的用户将被重定向到/login
。
但是,当我访问组件的直接路径时:
http://localhost/profile
验证始终返回false,任何用户(已记录或未记录)都将重定向到/login
。
// auth-guard.service.ts
export class AuthGuard implements CanActivate {
constructor(
private _authService: AuthService,
private _router: Router
) { }
canActivate(){
if (this._authService.checkAuth()){
return true;
}
this._router.navigate(['/login']);
return false;
}
}
// auth.service.ts
export class AuthService {
private _isLoggedIn:boolean;
private _userdata:any;
constructor(@Inject(Http) private _http: Http){
this._isLoggedIn = false;
this._userdata = {};
this.getProfile();
}
profileRequest():Observable<any>{
return this._http.get("..").map(res => res.json());
}
getProfile(){
this.profileRequest().subscribe(
success => {
this._isLoggedIn = true;
this._userdata = success.data;
},
error => {
this._isLoggedIn = false;
}
);
}
checkAuth():boolean{
return this._isLoggedIn;
}
}
// app.routing.ts
export const routing = RouterModule.forRoot([
{ path: '', component: AppComponent }
]);
// profile.routing.ts
export const profileRouting = RouterModule.forChild([
{
path: 'profile',
component: ProfileContainerComponent,
canActivate: [ AuthGuard ]
}
]);
我不确定,但这可能与http请求相关,该请求用于检查用户是否具有有效会话,因为所描述的问题在任何保护路由上都很开心。
无论如何,我现在都坚持这个。任何帮助将不胜感激。 感谢。
在跟踪我的身份验证类之后,我能够弄清楚导致这种情况的原因。
当我直接通过其Url访问路由时,在checkAuth
功能结束之前,正在运行路由保护的getProfile
功能。
由于此函数使用http请求,并且仅当在调用checkAuth
函数之前收到响应时流才起作用,因此该过程未按预期工作。
另一方面,当我通过应用程序访问路径时,初始的getProfile函数已经完成,允许设置路由保护中使用的变量。
修复(或解决方法)基于Wuno的方法,用于通过localStorage检查经过身份验证的用户。
用户登录/退出后,我已经设置/删除了localStorage密钥。
在类变量之前检查了此键。
// auth.service.ts
checkAuth(){
if (localStorage.getItem("USER_SESSION")){
return true;
}
return this.isLoggedIn;
}
如果您有更好的方法,请发送评论,我会更新帖子。 感谢。
答案 0 :(得分:1)
确保将[Guard]
添加到需要保护的完整路线。
因此,当我确保路线时,我将父母添加到app.routing.ts
const APP_ROUTES: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full', },
{ path: '', component: PublicComponent, data: { title: 'Public Views' }, children: PUBLIC_ROUTES },
{ path: '', component: SecureComponent, canActivate: [Guard], data: { title: 'Secure Views' }, children: SECURE_ROUTES }
];
export const routing = RouterModule.forRoot(APP_ROUTES);
确保注意到这一行,
{ path: '', component: SecureComponent, canActivate: [Guard], data: { title: 'Secure Views' }, children: SECURE_ROUTES }
所以我创建了2个布局
/ public /所有公共组件
<强> /public/public.routes.ts 强>
/ secure /所有安全组件
<强> /secure/secure.routes.ts 强>
安全路线
export const SECURE_ROUTES: Routes = [
{ path: '', redirectTo: 'overview', pathMatch: 'full' },
{ path: 'items', component: ItemsComponent },
{ path: 'overview', component: OverviewComponent },
{ path: 'profile', component: ProfileComponent },
];
app.routing.ts中的主要路线
const APP_ROUTES: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full', },
{ path: '', component: PublicComponent, data: { title: 'Public Views' }, children: PUBLIC_ROUTES },
{ path: '', component: SecureComponent, canActivate: [Guard], data: { title: 'Secure Views' }, children: SECURE_ROUTES }
];
export const routing = RouterModule.forRoot(APP_ROUTES);
在目录/ layouts中,我创建了一个
的布局<强> /layouts/secure.component.ts /layouts/secure.component.html /layouts/public.component.ts /layouts/public.component.html
所有内容都通过布局public
或secure
进行路由,[Guard]
处于安全状态。
然后我使用本地存储中的令牌处理身份验证。
@Injectable()
export class Guard implements CanActivate {
constructor(protected router: Router, protected auth: Auth ) {}
canActivate() {
if (localStorage.getItem('access_token')) {
// logged in so return true
return true;
}
// not logged in so redirect to login page
this.router.navigate(['/home']);
return false;
}
}
一旦我像这样设置我的应用程序,我将所有需要安全的路由放在安全目录和公共路径中。然后我在public.routes.ts文件或secure.routes.ts文件中创建它们各自的目录中的路由。