2

I have a login authorization module that is installed on my sql server.

The module is triggered from my web.config file in my wwwroot directory.

  <modules>
      <add name="PingAccessModule"/>
    </modules>

In normal use case

I connect to my website www.connecttosite.com -> module intercepts request and logs user in -> request is verified then sends additional http headers to my web api where I can read these additional headers and get the user information.

The problem is this requires me to create an additional asp.net web api project that exists in the same directory as my angular application.

I want to know is there a way using angular only that I can connect to the website -> angular makes a call somehow -> module intercepts call -> attaches extra information to response header and I can see this header in angular and not have to use web api at all?

Can I use angular to act as web api?

EDIT:

So the current answer works if I want to create my own headers but the login module attaches user info to the headers.

See the photo below:

enter image description here

  1. The authorization is the very first call in the stack (circled in green). This is the module intercepting the request to the website and logging the user in.

  2. The red arrow is the actual call to the angular website. Then you can see the normal angular modules (main.js, env.js, polyfills etc) loading after.

  3. When the initial call is made to the website, the headers that I need will be available even before angular loads all of the modules. How do I access them right when angular loads?

Terrance Jackson
  • 606
  • 3
  • 13
  • 40

2 Answers2

1

Try to use a mock api for your situation.

This should allow you to use angular as an api and call it from your normal angular client.

So you would serve it and call it like so

this.http.get('http://localhost:3000/api/YourMethodToGetUserInformation');
CodeMan03
  • 570
  • 3
  • 18
  • 43
0

Yes you can achieve this by using HttpInterceptor. HttpInterceptors allow you to return response directly instead of sending it to the server, modify request (URL, body, headers, etc) before sending it to the server and/or modify the response returned from the server.

For example the following interceptor return the response without making a server call if request url matches /my/path. It also modifies request

import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpResponse, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()
export class MyHttpInterceptor implements HttpInterceptor {

  public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (req.url === '/my/path') {
      // If request matches a certain url, do not call server and return result from angular
      return of(new HttpResponse({
        body: '{x: 1, y: 2}',
        headers: new HttpHeaders({
          'Content-Type': 'application/json'
        }),
        status: 200,
      }));
    }
    if (req.url === '/my/other/path') {
      // if request matches a certain url, modify the request before sending it to the server
      req = req.clone({
        setHeaders: {
          'X-MY-CUSTOM-HEADER': 'value'
        },
      });
    }
    // Pass the request to the next interceptor, if there are none, then the server is called.
    const result = next.handle(req);
    return result.pipe(
      map((response) => {
        // modify response from server here
        return response;
      }),
    );
  }
}

To use the interceptor, add it in app modules by providing HTTP_INTERCEPTORS as follows:

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
  ],
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: MyHttpInterceptor, multi: true},
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }
Sherif Elmetainy
  • 4,034
  • 1
  • 13
  • 22
  • So with // If request matches a certain url, do not call server and return result from angular return of(new HttpResponse({ body: '{x: 1, y: 2}', headers: new HttpHeaders({ 'Content-Type': 'application/json' }), status: 200, })); How do I get the response headers that are returned from the module? – Terrance Jackson Aug 17 '20 at 17:46
  • I should get response headers containing user information like UserID, and UserEmail – Terrance Jackson Aug 17 '20 at 17:46
  • By calling httpClient.get('/my/path', { observe: 'response' }), the return type will Observable> instead of Observable where T the type of Data received. In that case, you can use the HttpResponse properties to inspect the returned headers. In the interceptor, you can return a response with HTTP headers (as if they were returned from the server). of(new HttpResponse({ body: '{x: 1, y: 2}', headers: new HttpHeaders({ 'Content-Type': 'application/json', "UserID" : "123", "UserEmail": "x@y.z" }), status: 200, })); – Sherif Elmetainy Aug 17 '20 at 18:13
  • So basically, there are 2 parts for this. First is passing option to the HttpClient post/get/etc call in order to receive the full response headers instead of just the body. Second part is intercepting the http request and returning a response with body and headers as if it was returned by the server and skipping the server call. Both parts are not related, and can be used separately or together. – Sherif Elmetainy Aug 17 '20 at 18:16
  • See the update to the question above. I added a photo – Terrance Jackson Aug 17 '20 at 22:02
  • There is no way for angular to read the headers of a request that occurred before it was loaded. What you can do is create a second request after angular is loaded to the same URL with { observe: 'response'} and read the headers. For example httpClient.get('c21portal.dif.gwimnp.rpg', { observe: 'response' }).subscripe((response) => { // response.headers property contain the headers you want } – Sherif Elmetainy Aug 17 '20 at 23:43