skip to Main Content

I have a backend application in Spring Boot running on port 8080, and frontend React.js project running on port 3000. We are sending a request from React.js (port 3000) to Spring Boot /authenticate endpoint (port 8080) where it authenticates the login information and sends back a response. This works perfectly when running both application on my own computer. However, we need to use an vm and run the applications in separate docker containers. When the frontend is in an container, only the host can reach port 3000. Here is the Dockerfile we used for the frontend:

FROM node:alpine
RUN mkdir /app
WORKDIR /app
COPY package.json /app
COPY package-lock.json /app
RUN npm install
RUN npm install cors
COPY . /app
CMD ["npm", "start"]

This is the docker run command we used:

docker run -it -p 3000:3000 --name frontend-react group09/frontend-react

To allow other users than the host to reach port 3000, we used a nginx proxy to route traffic from port 80 to 3000. HOWEVER, when we did this we got an ERR: BLOCKED BY CLIENT message in the console. I will also attach the SecurityConfig we used in Spring Boot:

 @Override
    protected void configure(HttpSecurity http) throws Exception {
        // Allow JWT authentication
        http.cors().and().csrf().disable()
                .authorizeRequests()
                .antMatchers("/authenticate").permitAll()
                .anyRequest().authenticated()
                .and().sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        // Enable our JWT authentication filter
        http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);

        // Necessary authorization for each endpoint will be configured by each method, using @PreAuthorize
    }

Cors config:

@Bean
public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowCredentials(true);
    configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000","http://localhost:3000/","http://localhost:3000/login"));
    configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
    configuration.setAllowedHeaders(Arrays.asList("authorization", "withCredentials","content-type", "x-auth-token","Access-Control-Allow-Credentials","access-control-allow-origin","Access-Control-Allow-headers"));
    configuration.setExposedHeaders(Arrays.asList("x-auth-token","set-cookie"));
    configuration.setMaxAge(Duration.ofSeconds(5000));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

I really appriecate any tips on how to resolve this problem. We are pretty sure the problem isn’t within the code, as it runs completely fine when doing it outside of docker containers.

2

Answers


  1. Chosen as BEST ANSWER

    I figured out the problem after solid 20 hours. Basically we had to setAllowedOrigins to *, so that all IPs are allowed. To do this you also have to setAllowCredentials to false.


  2. Have you checked the referrer field in the request? Most probably, it is not localhost in this case, but rather you domain name.

    In this is the case, you need to add frontend_domain_name:3000 to your cors policy allowed origin field.

    Update: the answer which suggests to set allowed origin to *, actually, disables CORS as it allows all domains access your backend code, not just your frontend part.
    The correct way would be to add your_frontend_domain_name:3000 as allowed origin. This way your backend will be accessible only by users who are working through your frontend website.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search