How can I retrieve header values in the canActivate function in Angular?

Depending on the value of userRole received from the header, I need to redirect to different user pages.

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] }

I am initially redirected to the LoginComponent. The RandomGuard calls an API to fetch the header details from the server.

random.guard.ts

canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    return this.loginService.isHeader().pipe(
        map(e => {
            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; 
        })
    );
}

To receive the header value, it is necessary to subscribe to the http get call and refactor the code accordingly.

Answer №1

Utilizing Web API CORE in the backend, take a look at this specific API:

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

In this scenario, I include two headers: Roles containing its respective values and Access-Control-Expose-Headers indicating the names of headers we wish to access on the client-side, namely 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 retrieve them in Angular.

To observe the full response, ensure to pass observe: response into the options parameter like so:

isHeader(): Observable<boolean> {
    return this.http.get(`${environment.baseUrl}home/login`,{observe: 'response', withCredentials: true}).pipe(
        map((response: any) => {
           console.log(resp.headers.get('roles')); <-- Retrieving Roles value
           console.log(resp.body.someField); // Accessing requested body data type directly.
        })
    );
}

And here is the resulting header information:

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

Refer to HttpClient's documentation for more details.

Additionally, view the detailed explanation of Access-Control-Expose-Headers here.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

In Angular, what is the best way to update the quantity of an item in a Firestore database?

Whenever I attempt to modify the quantity of an item in the cart, the quantity does not update in the firestore database. Instead, the console shows an error message: TypeError: Cannot read properties of undefined (reading 'indexOf'). It seems li ...

The FireBase getToken function with the forceRefresh set to true has failed to perform as expected

I encountered a problem with this code snippet from Firebase when trying to run it in Angular 2 CLI. It gives an error of 'unreachable code'. How can I fix this issue and get it to work properly? firebase.auth().currentUser.getToken(/forceRefres ...

Can you explain the meaning of <T = MyType>?

While exploring a TypeScript file, I stumbled upon this interface declaration: interface SelectProps<T = SelectValue> extends AbstractSelectProps { /* ... */ } I've searched through the TypeScript handbook for <T = but couldn't find an ...

Data cannot be transferred to a child element unless it has been initialized during the definition phase

Passing an array data from parent to child component has brought up some interesting scenarios: parent.component.html: <child-component ... [options]="students" > </child-component> Status I: Setting the array on definition ...

Is it possible to declare an object literal with optional keys in a Typescript function signature?

I have a .d.ts file similar to this: declare function myfunc(): { something: (err, { req, res, errorInfo, query, pathname, extra }?) => void; }; This declaration states that the function takes two arguments, with the second argument being an optional ...

Creating a TypeScript generic type for the "pick" function to define the types of values in the resulting object

I am facing an issue while writing the type for the pick function. Everything works smoothly when picking only one key or multiple keys with values of the same type. However, if I attempt to pick a few keys and their values are of different types, I encoun ...

Can we make one tab disappear when another tab is clicked in Ionic 2 app menu icon?

I am working on a project using Ionic 2 and I have implemented multiple tabs in the application. However, I need to find a way to hide the top tab when the user clicks on the bottom tabs menu icon. Here is my Plunker for your reference. My goal is to ma ...

Angular 2: Enhancing Tables

I am looking to create a custom table using Angular 2. Here is the desired layout of the table: I have a Component that provides me with data export class ResultsComponent implements OnInit { public items: any; ngOnInit() { this.items = [&apos ...

Discover the power of merging multiple events in RxJS for efficient data retrieval and filtering

In various scenarios, I need to display a table of data with additional functionality for filtering and refreshing. The table is accompanied by two input fields - one for local filtering (searchLocal) and another for backend filtering (searchBackend). Ther ...

Enhancing TypeScript Data Objects

I'm looking to expand a data object in TypeScript by introducing new fields. Although I know it's a common practice in JavaScript, I'm struggling to get it to compile without making bar optional in the provided snippet. I am interested in f ...

Customize PrimeNG component styles

Utilizing the PrimeNG OverlayPanel for a dropdown click feature, I am encountering an issue with moving the default left arrow to the right position. Despite trying various solutions, I have reached a dead end. Would you be able to provide me with some fr ...

What is the best way to send multiple values from node.js to typescript?

My Node.js post API currently returns a token, but I want it to include the user's email, id, etc: app.post('/auth', function (req, response) { const body = req.body; console.log(req.body); let query = `select * from users wher ...

Angular2 routing directs me to a different URL path

In my Angular2 web application, I have set up the following routes: '', '/app', '/login', '/signin', '/validate', '/error', '**': I've defined a route configuration in app.router.t ...

"Upon receiving a request in Net Core 6 + Angular, null properties are detected in the

Greetings! I am currently working on a project using .NET Core 6 with Angular 12. Within my project, I have a login controller along with its corresponding request model. Interestingly, when I execute the request through Swagger or Postman, everything wo ...

Instructions on how to dynamically show specific text within a reusable component by utilizing React and JavaScript

My goal is to conditionally display text in a reusable component using React and JavaScript. I have a Bar component that I use in multiple other components. In one particular ParentComponent, the requirement is to show limit/total instead of percentage va ...

Incorporate Select2 functionality within the Angular2 application

I'm currently working on incorporating the Select2 plugin into my Angular2 application. Successfully, I have managed to set up select2 and transform my multiple select fields as expected. However, I am now facing a challenge in retrieving the selected ...

Limitations require a member to only accept a type (and not an instance) that extends or implements another type [TypeScript]

I'm seeking assistance with a set of abstract concepts in TypeScript. I am looking to restrict a member to only accept types as values, but those types must also implement or extend other types or interfaces. For example: The code snippet below is ...

Is there an array containing unique DateTime strings?

I am dealing with an Array<object> containing n objects of a specific type. { name: 'random', startDate: '2017-11-10 09:00', endDate: '2017-11-23 11:00' } My goal is to filter this array before rendering the resu ...

What are the typical scenarios where Angular's DI resolution modifiers are used?

Recently, I delved into the world of resolution modifiers, but I am struggling to grasp their practical application in my project. It appears that they are mainly used when dealing with services and requiring different instances of them in various parts of ...

The debate between using backticks and colons in TypeORM queries

Lately, I've been crafting queries utilizing backticks const firstUser = await connection .getRepository(User) .createQueryBuilder("user") .where(`user.id = '${id}'`) .getOne(); However, in the typeorm documentatio ...