В Angular -> как проверить, есть ли у пользователя разрешение на доступ на основе ролей с сохранением роли в базе данных. - PullRequest
0 голосов
/ 13 января 2019

Я пытаюсь сделать ролевый доступ к своему приложению в угловом формате, и мне нужна помощь, потому что я новичок в угловом ...

Во-первых, это то, что у меня есть в маршруте, где я устанавливаю, какие роли могут получить к нему доступ ...

из app-routing.module.ts

{
  path: 'profile',
  component: ComunityComponent,
  canActivate: [AuthGuard],
  data: {
    allowedRoles: ['admin', 'user']
  }
},

Во-вторых, я использую функцию canActivate, чтобы проверить, может ли пользователь получить доступ к маршруту или нет. от auth.guard.ts

private hasAccess: boolean;

constructor(private router: Router, private auth: AuthService) {}

canActivate(next: ActivatedRouteSnapshot,
              state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    const allowedRoles = next.data.allowedRoles;
    if (localStorage.getItem('currentUser')) {
      return this.checkAccess(localStorage.getItem('currentUser'), allowedRoles);
    }

    this.router.navigate(['/login'], {queryParams: {returnUrl: state.url}});
    return false;
  }

В-третьих, я разрабатываю функцию accessLoginToken, которая найдет роль зарегистрированного пользователя через службу httpclient.get, которая возвращает массив с ролями, назначенными пользователю. Пример {success: true, roles:['user']} от auth.service.ts

 accessLoginToken(token: string) {
    const check = '/users/access';
    const httpOptions = {
      headers: new HttpHeaders({
        'Authorization': 'Bearer ' + token,
      })
    };
    return this.http.get<any>('/api' + check, httpOptions).pipe(
      catchError(err => this.handleError('accessLoginToken', err))
    );
  }

Четвёртый в function checkAccess, я сравниваю его с данными маршрута, и если они совпадают, я разрешаю доступ, иначе нет. от auth.guard.ts

private checkAccess(token: string, allowedRoles: string[]): boolean {
    this.hasAccess = false;
    this.auth.accessLoginToken(token).subscribe(data => {
      if (data.success) {
        data.roles.forEach(rol => {
          if (allowedRoles.findIndex(rols => rols === rol) >= 0) {
            this.hasAccess = true;
          }
        });
      }
    }, (error) => {
      console.log(error);
    });
    console.log(this.hasAccess);
    return this.hasAccess;
  }

Основная проблема заключается в том, что я не могу заставить подписку httpclient изменить значение переменной hasAccess на true, чтобы разрешить доступ. Даже при выполнении кода this.hasAccess = true; функция возвращает false

Кстати, мне не нравится идея сохранения роли в переменной сеанса, такой как access_token, поэтому я пытаюсь сохранить ее в базе данных ...

любая помощь по этому вопросу будет оценена .. спасибо

Ответы [ 2 ]

0 голосов
/ 13 января 2019

Ваша проблема заключается в том, что вы возвращаете this.hasAccess, пока accessLoginToken все еще работает. Вы можете вернуть наблюдаемую угловую охрану.

0 голосов
/ 13 января 2019

Вы правы, функция checkAccess завершается до завершения асинхронного вызова API, поэтому всегда возвращается false. Вместо этого вы должны передать наблюдаемое методу canActivate.

private checkAccess(token: string, allowedRoles: string[]): boolean {
    this.hasAccess = false;
    return this.auth.accessLoginToken(token).pipe(
        map(data => {
            if (data.success) {
                data.roles.forEach(rol => {
                    if (allowedRoles.findIndex(rols => rols === rol) >= 0) {
                        this.hasAccess = true;
                    }
                });
            }
            return this.hasAccess;
        })
    )
}

Поскольку наблюдаемое возвращается в метод canActivate, охранник подпишется на наблюдаемое и будет ожидать истинного или ложного результата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...