0

I have an Angular 12 front-end application communicating with a Spring Boot back-end one. APIs shall be called passing a CSRF token using a cookie, but it seems like my logic is only working for localhost.

Please find the following snippets of code:

  • Angular cookie set through ngx-cookie-service:
this.cookieService.set(key, value, {
   secure: environment.apiHost.startsWith('https'),
   sameSite: environment.apiHost.startsWith('https') ? 'None' : undefined
});
  • Angular interceptor called before each request:
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    // Handle cookies
    request = request.clone({
      withCredentials: true
    });
    return next.handle(request).pipe(
      ...
    );
}
  • Spring Boot CORS general configuration:
List<String> allowedOrigins = new ArrayList<>();
allowedOrigins.add("http://localhost:4200");
allowedOrigins.add("https://<host_name_not_localhost>");

config.setAllowCredentials(true);
config.setAllowedOrigins(allowedOrigins);
config.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept"));
config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH"));
source.registerCorsConfiguration("/api/**", config);

return new CorsFilter(source);

I honestly don't understand if the issue lays in the front-end or in the back-end part... Again, sending cookies over HTTP (localhost) works fine, while the Cookie attribute doesn't appear when debugging the call over HTTPS.

Do you have any advice on this?

Thank you in advance.

AlexKibo88
  • 827
  • 1
  • 6
  • 16

2 Answers2

0

The only reason here could be that while creating cookie you are not setting domain with domain of backend. You can do something like

var cookieName = 'HelloWorld';
var cookieValue = 'HelloWorld';
var myDate = new Date();
myDate.setMonth(myDate.getMonth() + 12);
document.cookie = cookieName +"=" + cookieValue + ";expires=" + myDate 
                  + ";domain=.example.com;path=/";

In the above case example.com is your domain of backend. or by using cookies api, refer here :- https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Work_with_the_Cookies_API

Aakash Garg
  • 10,649
  • 2
  • 7
  • 25
  • Hi, that is actually not true: the cookies are correctly set in the browser with the same domain of the back-end. Besides, they are stored as "secured" and with the "None" as the SameSite attribute. The only difference is the path: the BE has "DTM-BE" after the domain, while the cookies is set with "tbx-app" as the path. I.E. https:///DTM-BE/api/... is the BE, while the cookie has domain and path "/tbx-app". – AlexKibo88 Feb 15 '22 at 16:10
  • you are sure that interceptor you are using is there in production? – Aakash Garg Feb 15 '22 at 16:14
  • please also check if cookie have valid path and isn't expired. – Aakash Garg Feb 15 '22 at 16:16
  • The interceptor works fine, because it also handles errors and those appear correctly. The expiration is currently not set, as you can see from the code, so they are stored as "Session" cookies. I don't think that's the issue... – AlexKibo88 Feb 15 '22 at 16:19
  • and you are not getting cookie in request headers? – Aakash Garg Feb 15 '22 at 16:23
  • Exactly. Cookies are correctly stored in the browser by the first code snippet I reported, by when the call is performed and the interceptor captures the request, I can't see any cookies in the request header. – AlexKibo88 Feb 16 '22 at 07:42
  • you might not see them in interceptor but should receive them at backend. – Aakash Garg Feb 16 '22 at 12:42
0

I decided to get rid of the cookies and pass the information in the request header, which seems to be a much more secure approach. Plus, I can control the allowed headers from the back-end itself.

AlexKibo88
  • 827
  • 1
  • 6
  • 16