【发布时间】:2019-11-30 04:42:50
【问题描述】:
我尝试在我的项目中实现身份验证服务。 后端为我提供 sso 令牌和当前用户权限。
{
"success":true,
"data: [
{
"first_name":"Michel",
"last_name":"Drucker",
"email":"mdrucker@fr3.com",
"company":"fr3",
"image":"http://micheldrucker.com/moi.jpg",
"permissions":["ADMIN"]
}
]
}
我想在本地存储中设置这些数据,但我的守卫不会等待这些数据被设置。
所以我在警卫中的验证不起作用,我有一个错误
Cannot read property 'data' of null.
为了防止这个错误,我设置了一个item的权限,之前处理像localStorage.setItem('permissions', 'xxx');
app.component.ts
使用事件快照保存来自 url 的令牌
this.router.events.subscribe((event: Event) => {
// put sso and permissions in local storage
if (event instanceof ChildActivationStart) {
if (event.snapshot.queryParams.sso !== undefined) {
localStorage.setItem('sso', event.snapshot.queryParams.sso);
this.apiService.permissions().subscribe((data) => {
localStorage.setItem('permissions', data.data[0].permissions);
});
}
}
});
authorization.guard.ts
检查路由权限规则,如果未授权则阻止用户
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
// declaration of route roles path
const allowedRoles = next.data.permissions.only;
// check if user is authorized
const isAuthorized = this.authorizationService.isAuthorized(allowedRoles);
if (!isAuthorized) {
this.snackbarMessage.openErrorSnackBar(this.translate.instant('GUARD.UNAUTHORIZED'));
this.router.navigate(['/']);
}
return isAuthorized;
}
authorization.service.ts
控制用户
isAuthorized(allowedRoles: string[]): boolean {
// check if the list of allowed roles is empty, if empty, user can access
if (allowedRoles == null || allowedRoles.length === 0) {
return true;
}
// get permissions stored at app init after login
const permissions = localStorage.getItem('permissions');
// if it's not exists, delete sso token and go back to login
if (!permissions) {
localStorage.removeItem('sso');
this.router.navigate(['/login']);
}
// check if user has route allowed roles
const rolesIsFound = allowedRoles.filter(element => permissions.includes(element));
let userAuthorized = false;
if (rolesIsFound.length > 0) {
userAuthorized = true;
}
return userAuthorized;
}
route.ts
{
path: '',
component: FuseHomeComponent,
canActivate: [AuthorizationGuard],
data: {
permissions: {
only: ['ADMIN'],
}
}
},
auth-interceptor.ts
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const sso = localStorage.getItem('sso');
if (sso) {
request = request.clone({
setHeaders: {
'Content-Type': 'application/json',
'X-API-KEY': sso,
}
});
}
return next.handle(request).pipe( tap(() => {},
(err: any) => {
if (err instanceof HttpErrorResponse) {
if (err.status !== 401) {
return;
}
localStorage.removeItem('sso');
localStorage.removeItem('permissions');
this.snackbarMessage.openErrorSnackBar(this.translate.instant('GUARD.UNAUTHORIZED'));
this.router.navigate(['/login']);
}
}));
}
我不认为我的代码很好,将数据存储在应用程序组件中似乎不太好。通过设置权限“xxx”,用户可以在几秒钟内访问应用程序,直到 http 响应禁止用户访问。我认为这只是一个“等待”的问题。
【问题讨论】:
标签: angular authentication wait guard