2

I'm developing an app using Ionic Framework and generated a JHipster project for my backend. My JHipster project runs on an extra Server and is called via REST requests from my App. So my problem now is handling the CORS and CSRF configuration.

My JHipster project has its own frontend, which runs on the same domain and while testing I can reach my backend without any issues. However, when I want to call my backend on the server from my Ionic app my xsrf tokens wont update properly and, therefore, I cannot access my backend. I already tried several solutions from different stack overflow posts, but none of them worked for me.

For example:

What I've done so far:

  1. I enabled csrf in my SecurityConfiguration in my JHipster project
        http
            .csrf()
            .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            .and()
            .addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
            .exceptionHandling()
            .authenticationEntryPoint(problemSupport)
            .accessDeniedHandler(problemSupport)
  1. added CORS configuration
  cors:
    allowed-origins: 'http://localhost:8100, ionic://localhost, http://localhost'
    allowed-methods: 'POST, GET, OPTIONS, DELETE, PUT, HEAD'
    allowed-headers: 'Origin, X-Requested-With, Content-Type, Accept, x-auth-token, Authorization, X-CSRF-Token, x-xsrf-token, XSRF-TOKEN'
    exposed-headers: 'Authorization,Link,X-Total-Count,XSRF-TOKEN, X-XSRF-TOKEN'
    allow-credentials: true
    max-age: 86400
  1. wrote an interceptor
@Injectable()
export class HttpXSRFInterceptor implements HttpInterceptor {

  constructor(private tokenExtractor: HttpXsrfTokenExtractor, private csrfService:CSRFService,  private $sessionStorage: SessionStorageService) {
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const headerName = 'XSRF-TOKEN';
    const respHeaderName = 'X-XSRF-TOKEN';
    let token = this.tokenExtractor.getToken() as string;

    if (token !== null && !req.headers.has(headerName)) {
      req = req.clone({ headers: req.headers.set(respHeaderName, token) });
      req.clone({
        withCredentials: true
      });
    }
    return next.handle(req);
  }
}
  1. added HttpClientXsrfModule in my app.module.ts and the interceptor
    HttpClientXsrfModule.withOptions({
      cookieName: 'XSRF-TOKEN',
      headerName: 'X-XSRF-TOKEN',
    }),
    {
      provide: HTTP_INTERCEPTORS,
      useClass:  HttpXSRFInterceptor,
      multi: true
    },

My Problem:

I dont get a xsrf token when starting my App in the browser, but after I send a post request the token gets set as a cookie.

For example when logging in, the first attempt fails due to the missing token, but the second login request is successful because now the response header for the xsrf token is not null anymore. Furthermore, the token does not update itself even though the server response has a new token in its header.

From my understanding

  1. the first time I get my token should be immediately after loading the start page of my app

  2. the token should be updated after each response from the server (backend) and the updated token is used for the next request

Therefore my problem is that both these issues do not happen and I don't know how to fix it.

I appreciate any help!

cheers

lisa
  • 21
  • 3

1 Answers1

2

I'm the author of Ionic for JHipster so hopefully, I can help you with this.

First of all, CSRF shouldn't be an issue unless you're running your apps on the same port. In my experience, when you run them on separate ports, your client can't read the cookie. As for CORS, that's not a problem for me when running locally. I believe it's because the CORS settings for the dev profile are wide open. Can you try using the settings from the dev profile in your prod profile and see if it helps?

For reference, they are:

jhipster:
  cors:
    allowed-origins: '*'
    allowed-methods: '*'
    allowed-headers: '*'
    exposed-headers: 'Authorization,Link,X-Total-Count'
    allow-credentials: true
    max-age: 1800

If this works, I'd try changing your allowed origins to an array, or just use one. http://localhost:8100 should be all you need if running locally.

Matt Raible
  • 8,187
  • 9
  • 61
  • 120
  • If this works, I'd try changing your allowed origins to an array: – Matt Raible Apr 07 '20 at 17:53
  • So I tried changing my cors settings as you suggested, but I get "Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-XSRF-TOKEN'" as response message. Maybe I understood something wrong but if I am testing my backend on localhost:8080 and my ionic app on localhost:8100 I would get problems because the different ports? Or do I get problems with my configuration because I am running my backend on a different domain as my ionic app? – lisa Apr 08 '20 at 08:31