Skip to content
This repository has been archived by the owner on Jun 8, 2021. It is now read-only.

Getting the Request server side #28

Closed
RadouaneRoufid opened this issue Sep 28, 2018 · 10 comments
Closed

Getting the Request server side #28

RadouaneRoufid opened this issue Sep 28, 2018 · 10 comments

Comments

@RadouaneRoufid
Copy link

I need to get the request header server side, in my app.component. I tried the code below but does not work.

import { Request } from 'express';
import { REQUEST } from '@nguniversal/express-engine/tokens';

const lang = isPlatformServer(this.platformId) ?
            this.request.headers['accept-language'] :
            this.translateService.getBrowserLang();

I also tried with

injector. injector.get(REQUEST);

@RadouaneRoufid
Copy link
Author

Any news on this ?

@RadouaneRoufid
Copy link
Author

Any news please ?

@swaechter
Copy link
Owner

Hey Radouane

It's a good idea to take a look at the first image in this issue: angular/angular#22443

There you can see that there are two types of requests and responses:

1.) Step 1 and 6, made from the end user/client to the Java web server and back
2.) Step 4 or in general requests done in the J2V8 Node.js instance

Now this results in a problem where the two requests/responses don't share their data, means: A cookie received by the web server won't be passed down to the J2V8 Node.js requests and their responses won't be updated/merged with the Java response to the end user.

Using express-engine/tokens to parse/read/update cookies won't solve this problem - we simply need a bridge to pass down/up all headers (and thereforce values like session ID and cookies).

I asked in angular/universal#1000 if there is such a feature (Sadly there isn't) and at the moment I just don't have the time and resources to write one by myself (I guess I have to do it after Christman and before New Year). So at the moment I can't offer you a fix/solution :/

@RadouaneRoufid
Copy link
Author

Thank you for the detail.

I didn't succeed to find any workaround, I will wait your future work.

Regards.

@RadouaneRoufid
Copy link
Author

Hi @swaechter,

Happy new year :) !

Do you had time to work on this thread ?

Thank you,

@RadouaneRoufid
Copy link
Author

RadouaneRoufid commented Jan 14, 2019 via email

@swaechter
Copy link
Owner

Hey not yet, but the new TCP solution uses the official Angular Universal interface/library now.

So it might be a good idea to propose more sophisticated features on the official project there:

  • Hash map to pass down general data like server URL/port, so you don't have to hard code them in your Angular app
  • Cookie API so existing [Java-]cookies can be passed down and later retrieved [and updated in Java]

You can find the thread here: angular/universal#1000

@RadouaneRoufid
Copy link
Author

Hi,

It seems that socket-engine does not support getting request server side actually. I created this feature angular/universal#1136

For now, I want to know if is there any fast way to get the cookie server side using socket-engine or the previous registerRenderAdapter.

I don't know v8 well, it would be nice if you can show me where I can do the evolution.

@swaechter
Copy link
Owner

Yes, that's more or less the problem. A working solution for Java --> Node.js TCP server with Angular Universal --> Java could look like this (Note: I deprecated the V8 implementation in favor of the Angular Universal implementation):

1.) Get all cookie values via the Spring Boot/servlet cookie API and store them in a map
2.) Extend the Java to Node.js TCP mechanism to pass down all these cookie values via the map
3.) In Angular, create a cookie service with the cookie map as input values
4.) Do your SSR work and use the cookie service
5.) Send back the rendered result + the potentially updated cookies back to the Java server
6.) Update the Java cookies with the potentially updated cookie map
7.) Send the SSR result back to the client

Caveats: It's not possible to "simulate" cookie values with a set httpOnly flag (https://www.owasp.org/index.php/HttpOnly) - you just can't protect them properly in the Node.js engine

At the moment I just don't have the time to tinker around with 3 - 5 (1, 2, 6 and 7 should be quite easy to accomplish).

@RadouaneRoufid
Copy link
Author

Hi,

I implemented the solution for v8. In back-end server, i fetch the request context that i inject to the angular as below :

renderPage(uuid: string, uri: string, context: string) {
        renderModuleFactory(this.appservermodulengfactory, {
            document: this.html,
            url: uri,
            extraProviders: [
                provideModuleMap(this.lazymodulemap),
                {provide: BC_CONTEXT, useValue: JSON.parse(context)}
            ]
        }).then(html => {
            receiveRenderedPage(uuid, html, null);
        });
    }

I can then retieve the context using injector

if (isPlatformServer(platformId)) {
            const context: RequestContext = injector.get(BC_CONTEXT);
}

It's works well. I will migrate to TCP solution once it's mature.

Thank you for your help.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants