Angular how to get headers value in the canActive

2020-02-07 06:09发布

问题:

I need to redirect into different user page depends on the userRole value received from the header.

angular.routing.ts

{ path: '', pathMatch: 'full',  redirectTo: '/login' },
{ path: 'user', loadChildren: './home/home.module#HomeModule', canActivate: [AuthGuard], data: { roles: Role.User} },
{ path: 'admin', loadChildren: './somemodule#SomeModule', canActivate: [AuthGuard], data: { roles: Role.Admin}},
{ path: 'login', component: LoginComponent, canActivate: [RandomGuard] }

Initially I'm redirecting into LoginComponent, CanActive random.guard.ts is a API call to get the header details from server.

random.guard.ts

canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    return this.loginService.isHeader().pipe(
        map(e => {
            // the problem is e.headers.get('userRole') undefined
            if (e.headers.get('userRole') === 'user') {
                this.router.navigate(['/user']);
            } else if(e.headers.get('userRole') === 'admin') {
                this.router.navigate(['/admin']);
            } else { 
                return true;
            }
        }),
        catchError((err) => {
            this.router.navigate(['/login']);
            return of(false);
        })
    );
}

loginservice.ts

isHeader(): Observable<boolean> {
    return this.http.get(`${environment.baseUrl}home/login`,{observe: 'response'}).pipe(
        map((response: any) => {
            return response; 
            // response i did't get header value 
            // how to receive header value on here
        })
    );
}

If i subscribe the http get call, i will get the header value. How to refactor the code and recieve he header value.

回答1:

In the backend I'm using Web API CORE, look at the following API:

[HttpGet]
[Route("admins/overview/{id}")]
public IActionResult GetOverview(int id)
{
    var item = _adminService.GetOverviewById(id);
    Response.Headers.Add("Roles","Admin,User,Editor");// Here we add the roles with its values to Header
    Response.Headers.Add("Access-Control-Expose-Headers", "Server,Roles"); // specify the name of headers to access
    return Ok(item);
}

Here, I add tow headers : the first one is Roles with its values and the second one in Access-Control-Expose-Headers with the name of headers that we want to access them in client-side that they are Server,Roles

By default, only the 6 CORS-safelisted response headers are exposed:

Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma

Now, You can access them in Angular.

You can observe the full response, to do that you have to pass observe: response into the options parameter

try this:

isHeader(): Observable<boolean> {
    return this.http.get(`${environment.baseUrl}home/login`,{observe: 'response', withCredentials: true}).pipe(
        map((response: any) => {
        // Here, resp is of type HttpResponse<Sth>.
        // You can inspect its headers:
           console.log(resp.headers.get('roles')); <-- Get Value of Roles
        // And access the body directly, which is typed as MyJsonData as requested.
           console.log(resp.body.someField);
        })
    );
}

And finally this is the result:

server: Kestrel
content-type: application/json; charset=utf-8
roles: Admin,User,Editor

See this-> HttpClient's documentation

and -> complete explanation of Access-Control-Expose-Headers