Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

CanActivate com HttpClient - Angular 2

Estou com um problema que tento resolver há horas e não encontrei solução. Fiz um guarda de rotas para verificar se o usuário está autenticado. A interface que devemos assinar é a CanActivate. Ele pede a implementação do método canActivate que retorna um Observable<-boolean> | boolean. Minha classe está assim:

Método canActivate do AuthGuard:

@Injectable()
export class AuthGuard implements CanActivate {
    constructor(private _router: Router, private _userService: UserService) {}
    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean {
       return this._userService.getUserAuthenticated().map(
            user => {
                this._userService.setUser(user);
                return user ? true : false;
            }
        )
    }
}

Classe UserService:

...    
    private user:any;
    constructor(private http: HttpClient) {}
    setUser(user) { this.user = user; }
    getUserAuthenticated():Observable<any>{
        return this.http.get(
            apiUrl+'/auth/validate-token', 
            { headers: getHeaders() }
        );
    }

Meu problema é: Quando uso o método .map no getUserAuthenticated().map(...) eu não consigo de jeito nenhum usar um Handling de erros. Como a api retorna um status 403, o console acaba exibindo a pilha de erros.

Quando uso o subscribe getUserAuthenticated().subscribe()... eu consigo pegar os erros do HttpClient, porém meu canActivate não retorna true. Como a chamada é assíncrona, ele chama o serviço que verifica a autenticação e vai embora de vez. Assim sempre tenho um false como resposta. Mesmo com o usuário devidamente autenticado.

Alguém tem uma luz? Exemplo de como ativar isso?

2 respostas

Fala manoel, tudo bom? Eu não entendi bem, mas usando o httpClient, se você quiser ter acesso ao response o código da chamada fica assim:

const get = this.httpClient.get('URL', { observe: 'response' })

get.subscribe( ... )
solução!

Fala, Mario. Eu entendo o acesso ao response do HttpClient. O erro estava bem além disso.

Percebi o problema aqui e já foi resolvido. Estava seguindo uma estrutura não muito adequada.

O meu método canActivate de AuthGuard usava do UserService para saber se o token atual do sistema estava válido. Em resumo, ele chamava o UserService, que fazia um get na api para validar o token, assim a api retornava um status adequado. Essa abordagem não é a melhor. O mais interessante é usar no próprio projeto do Angular um TokenHelper que valida o tempo do próprio token. Assim dentro do canActivate posso determinar se o usuário pode ou não seguir a rota.

Obrigado pela atenção no meu caso.

Abraço!