0

I have a hybrid angular/angularJS app that seems to work well as basically just a wrapper for angularjs. We're not currently using any angular components or services, all logic still exists in angularjs.

As a step forward to migrating into angular, I'm trying to write a new component to display some data, but I'm finding that when I make http requests, it doesn't seem to be using the same session that exists under angularjs. The exact same http request under angularJS works just fine, but under Angular, I'm no longer authenticated. Login/authentication happens under the AngularJS logic but since both angularjs and angular are effectively the same "app" once compiled, I'm not sure how this isn't working.

Why is this, and how can I fix it? I have no idea what information/code is helpful to see in this scenario as I'm not entirely sure what's even wrong here.

This is in my constructor for the Angular component:

private _listHealthDataUrl: string = "http://localhost:6543/rpc/json/health/get_health_entries";

getData(): Observable<IHealthResponse> {
    return this.http.post<IHealthResponse>(this._listHealthDataUrl, {}, {})
}

And the exact same request done from within angularJS:

$http({
    url: 'http://localhost:6543/rpc/json/health/get_health_entries',
    method: 'POST',
    data: {}
    }
}).then(function (e) {...})

The request headers, as far as what Chrome tells me, are exactly the same:

Provisional headers are shown
Accept: application/json, text/plain, */*
Content-Type: application/json;charset=UTF-8
Origin: http://localhost:8080
Referer: http://localhost:8080/health
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36

The request headers as for what the server seems to read:

{'Origin': 'http://localhost:8080', 'Content-Length': '2',
 'Cache-Control': 'no-cache',
 'Accept': 'application/json, text/plain, */*',
 'Content_Length': '2',
 'Referer': 'http://localhost:8080/bloodpressure',
 'Content-Type': 'application/json',
 'X-Appengine-Country': 'ZZ',
 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36',
 'Pragma': 'no-cache', 
 'Accept-Language': 'en-US,en;q=0.9', 
 'Host': 'localhost:6543', 
 'Content_Type': 'application/json'}

Again, exactly the same except on the AngularJS, the headers include a session header. I'm not sure where that comes from on AngularJS side of things or why Angular doesn't have include it.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
Jer_TX
  • 465
  • 4
  • 20
  • look to see if AngularJS has an interceptor in the router that adds authentication. In your Angular project the wrapper your API request might be missing cookies or bearer token for authentication. Check all the properties in the HTTP request from the AngularJS and Angular component and see what headers are missing – Andrei Apr 25 '19 at 18:59
  • In hybrid apps AngularJS and Angular exist as separate, independent frameworks that simply interoperate. I wonder if each framework is keeping its own storage, which is causing the issue. I'd open up the storage tab in dev tools and have a look. –  Apr 25 '19 at 19:11
  • @Andrei Looking at the request headers themselves from server-side, they are exactly identical between eachother, but the AJS side sends up a Session header (not something I'm explicitly doing in my code) and that header is absent from the Angular request. – Jer_TX Apr 25 '19 at 19:15
  • @javascript-sucks I see nothing in Local Storage and Session Storage – Jer_TX Apr 25 '19 at 19:15
  • @JeremyDavis take a look at them from the client side just in case via network tab. I agree that server side should tell you exactly what the headers received should be but perhaps it's already after authentication and it might have stripped that data out. Take a look at what the client is sending there needs to either a) be a cookie or b) special header for authentication. only other thing which doesn't make sense is if the authentication is always sent as part of the body. – Andrei Apr 25 '19 at 19:18
  • @JeremyDavis based on your update I have a good hunch your AngularJS is using $http interceptor to add authentication headers https://docs.angularjs.org/api/ng/service/$http#interceptors try and find that logic. – Andrei Apr 25 '19 at 19:22
  • @Andrei updated my question with more details. As far as the interceptor, I did a ctrl+f in the entire project/directory and there's no such logic. – Jer_TX Apr 25 '19 at 19:30
  • @JeremyDavis let's work backwards, how does your server authenticate a client? start from there and work your way to see how a client is authenticated. Unfortunately there isn't just 1 way to authenticate a user so you need to figure that out first. Once you know update the question. Based on the updated question with the **content-headers** it appears there is no authentication? can you show the HTTP error should be a 400 for **unauthorized** EDIT: is that the **HTTP Request headers** from chrome network dev tools? – Andrei Apr 25 '19 at 19:39
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/192390/discussion-between-andrei-and-jeremydavis). – Andrei Apr 25 '19 at 19:42

1 Answers1

1

The problem was $http's default options withCredentials. I was mistaken in that it wasn't a session header, but a cookie with the name session. massive facepalm.

In angularJS, you can simply do

$http.defaults.withCredentials = true;

from within .run() but seems angular doesn't have such a thing. Fix there is using an interceptor on HttpClient, or otherwise including withCredentials on the options section of every http request.

Jer_TX
  • 465
  • 4
  • 20