1

I have an Angular app on http://localhost:4200/myfrontend that gets data from a Java REST api on http://localhost:8080/mybackend. Within the Angular app though, every time I reach out to the REST api a new session is created.

I created a test where I put both frontend and backend on http://localhost:8080 and the session was not lost.

The settings I set for the Java REST backend are:

response.getHeaders().add("Access-Control-Allow-Origin", "*");
response.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
response.getHeaders().add("Access-Control-Allow-Credentials", "true");
response.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");

The settings I set for the Angular 6.0.5 frontend are:

const httpOptions = {
  headers: new HttpHeaders({
    'Content-Type': 'application/json'
  })
};

What must I do to keep alive the session when the frontend and backend URL are both different? Is this a missing CORS setting?

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Socrates
  • 8,724
  • 25
  • 66
  • 113
  • 2
    Sessions are managed as cookies. Cookies are forwarded from a browser to the server-side if the domain is the same when the domain is different your session cookie gets created each time – Lasitha Petthawadu Jun 02 '18 at 01:31
  • 1
    REST API is stateless. So using sessions is error prone approach. – Mara Jun 02 '18 at 11:03
  • @Mara Isn't that a matter of decision to make when it comes to scalability? Both stateless and stateful are possible solutions for REST (https://stackoverflow.com/questions/34130036/how-to-understand-restful-api-is-stateless). – Socrates Jun 02 '18 at 14:34
  • @LasithaPetthawadu Cookies might be an alternative and would also enable stateless REST, right? Do you have a good stepwise tutorial for that? – Socrates Jun 02 '18 at 14:35
  • @Socrates What I meant was currently your loosing the session mainly because the session uses cookies, and cookies don't pass between different domains, since your port number is different the java session cookie doesn't pass. – Lasitha Petthawadu Jun 03 '18 at 02:31
  • 2
    @Socrates I prefer official documentation first and only if I can't find answer there I go to stackoverflow. So doc is here http://www.restapitutorial.com/lessons/whatisrest.html# And it says: In REST, the client must include all information for the server to fulfill the request, resending state as necessary if that state must span multiple requests. Statelessness enables greater scalability since the server does not have to maintain, update or communicate that session state. Additionally, load balancers don't have to worry about session affinity for stateless systems. – Mara Jun 03 '18 at 08:20
  • @Mara I'm starting to think that if the REST api is stateless, then every REST call should only be POST and not GET, PUT, DELETE. The reason is that I can easily provide all the credential information to the server using a JSON string. The desired action can be written within the JSON string. – Socrates Jun 04 '18 at 12:41
  • 2
    @Socrates Please read carefully wiki about REST services https://en.wikipedia.org/wiki/Representational_state_transfer . Pay attention on "Architectural constraints" section and "Statelessness" subsection. According to it REST services doesn't have session, all needed data are sent to server in every request. If there is session on server, it's not REST. – witalego Jun 04 '18 at 12:56
  • 3
    @Socrates And there are other places to send data except url and body, for example headers, so you can use all HTTP methods, not only POST. – witalego Jun 04 '18 at 13:03

1 Answers1

2

Currently, both URLs have their own individual sessions. What you essentially need is a "backend to backend” communication. You can achieve this by using a dev-server proxy.

A dev-server proxy is a piece of software which is in between your JavaScript/Angular app doing the Ajax request and your backend API.

So, Assuming Instead of doing this -

this.http.get('http://you-server-hostame:8080/mybackend/...')
.map(res => res.json());

Use

this.http.get('/mybackend/')
.map(res => res.json());

Create a proxy.conf.json file at the root of your angular CLI project.

{
 "/mybackend/*": {
"target": "http://8080:<your service port>",
"secure": false,
"logLevel": "debug",
"changeOrigin": true
 }
}

All requests made to /mybackend/... from within our application will be forwarded to http://8080:/....

Also now for starting the server you need to use

ng serve --proxy-config proxy.config.json

Note :the changeOrigin property. You will definitely have to set this to true when you’re using some virtual proxies (such as configured with Apache2) on your backend.

What it does is to simply take the browser request at the same domain+port where you frontend application runs and then forwards that request to your backend API server.

Disclaimer: Not recommended for Production

Atul
  • 521
  • 1
  • 7
  • 20
  • Why don't you recommend this for production? – Socrates Jun 13 '18 at 06:58
  • in prod..when request done from browser it uses ‘origin’ header, that ‘tells’ server where this request came from. In case angular hosted at APIs server the origin header will set with same host (so no cross origin problems will prevent it). problem only if you run angular on node @ 4200 – Atul Jun 13 '18 at 07:23