angular / angular

Deliver web apps with confidence 🚀
https://angular.dev
MIT License
94.71k stars 24.68k forks source link

Angular SSG: Incompatibility between withXsrfConfiguration( ) (HttpClient) & Relative Paths in SSG #55635

Open surajchopra1234 opened 2 weeks ago

surajchopra1234 commented 2 weeks ago

Which @angular/* package(s) are the source of the bug?

common

Is this a regression?

Yes

Description

Conclusion

Please provide a link to a minimal reproduction of the bug

No response

Please provide the exception or error you saw

No response

Please provide the environment you discovered this bug in (run ng version)

Angular CLI: 17.3.2
Node: 21.7.1 (Unsupported)
Package Manager: npm 10.5.2
OS: win32 x64

Angular: 17.3.1
... animations, cdk, common, compiler, compiler-cli, core, forms
... material, platform-browser, platform-browser-dynamic
... platform-server, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1703.2
@angular-devkit/build-angular   17.3.2
@angular-devkit/core            17.3.2
@angular-devkit/schematics      17.3.2
@angular/cli                    17.3.2
@angular/ssr                    17.3.2
@schematics/angular             17.3.2
rxjs                            7.8.1
typescript                      5.2.2
zone.js                         0.14.3

Anything else?

No response

alan-agius4 commented 2 weeks ago

Hi @surajchopra1234, are you using withFetch? and which Angular CLI builders are you using?

surajchopra1234 commented 2 weeks ago

Hi @alan-agius4

I am using withFetch and new application builder in angular.

alan-agius4 commented 2 days ago

It seems that XSRF does not work for URLs with protocols due the implementation in the framework, see: https://github.com/angular/angular/blob/f1e3ec2601dac808af87137bc5ae5e28f512e9f4/packages/common/http/src/xsrf.ts#L100-L101

This limitation is due to variations in the cookies set across different origins. However, it doesn't handle the case of a cookie being shared between sub-domains. Can you confirm if this is the type of cookie in your scenario?

Protocol-less URLs, are solely managed by browsers, thus incompatible with environments like Node.js. The browser determines the protocol based on the current page, making this feature nonfunctional on servers. Additionally, the usage of protocol-less URLs has become less common due to various drawbacks:

  1. Security Vulnerabilities: Protocol-less URLs pose a risk of "man-in-the-middle" attacks, particularly on HTTP-served sites.
  2. Performance Implications: Browsers may encounter delays in loading resources as they determine the correct protocol.
  3. Mixed Content Concerns: Integrating protocol-less URLs that load over HTTP within secure HTTPS pages can trigger mixed content warnings in browsers.

On the server side while doing SSG/SSR, the XSRF token currently is being noop'd. see: https://github.com/angular/angular/blob/f1e3ec2601dac808af87137bc5ae5e28f512e9f4/packages/common/http/src/xsrf.ts#L74-L76 While it's feasible to adjust this behavior for SSR, in the case of SSG, the token will remain undefined. This occurs because there is no request during SSG, preventing retrieval of the cookie from the document or request.

This would require the framework to support a different approach, either by setting an value of the token via an environment variable example XSRF_TOKEN="blabla" ng build or being set in the application as a DI token.

const serverConfig: ApplicationConfig = {
  providers: [
    provideServerRendering(),
    {
      provide: XSRF_TOKEN,
      useFactory: () => generateXsrfToken()
    }
  ]
};
surajchopra1234 commented 2 days ago

Hi @alan-agius4,

Thank you for working on this issue.

Backend: Located at api.domain.com

Angular App: Running on www.domain.com

XSRF Cookie: Domain is set to.domain.com, making it accessible from both api.domain.com and www.domain.com

Proposed Solution: