CORS error after hosting application on Railway

171 Views Asked by At

I hosted my frontend (react) and backend (springboot) subfolders separately on Railway. I am getting CORS error after updating the origin where the frontend is deployed as follows:

This is my configuration in spring:

@Configuration
public class DataRestConfig implements RepositoryRestConfigurer {
    private String theAllowedOrigins = "https://finance-app-frontend-production-7ab9.up.railway.app";
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) {
        HttpMethod[] theUnsupportedActions = {HttpMethod.PATCH};
        config.exposeIdsFor(Expense.class);
        config.exposeIdsFor(Goal.class);
        // disable HTTP methods
        disableHttpMethods(Expense.class, config, theUnsupportedActions);
        disableHttpMethods(Goal.class, config, theUnsupportedActions);

//        Configure CORS Mapping
        cors.addMapping(config.getBasePath() + "/**")
                .allowedOrigins(theAllowedOrigins).allowedMethods("GET", "POST", "DELETE", "PUT");
    }

    private void disableHttpMethods(Class theClass, RepositoryRestConfiguration config, HttpMethod[] theUnsupportedActions) {
        config.getExposureConfiguration()
                .forDomainType(theClass)
                .withItemExposure((metadata, httpMethods) -> httpMethods.disable(theUnsupportedActions))
                .withCollectionExposure((metadata, httpMethods) -> httpMethods.disable(theUnsupportedActions));
    }
}

and

package com.example.demo.config;
import com.okta.spring.boot.oauth.Okta;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.accept.ContentNegotiationStrategy;
import org.springframework.web.accept.HeaderContentNegotiationStrategy;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.Arrays;


@Configuration
public class SecurityConfiguration {


    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        // Disable cross site request forgery
        http.csrf(csrf -> csrf.disable())
                .cors(cors -> {
                    cors.configurationSource(corsConfigurationSource());
                }

                )

                // Protect endpoints at /api/<type>/secure
                .authorizeHttpRequests(auth -> auth
                                .requestMatchers("/api/expenses/**").authenticated()
                                .requestMatchers("/api/goals/**").authenticated()
                )


                .oauth2ResourceServer((oauth2) -> oauth2
                        .jwt(Customizer.withDefaults())
                )

                // Add content negotiation strategy
                .setSharedObject(ContentNegotiationStrategy.class,
                        new HeaderContentNegotiationStrategy());
        Okta.configureResourceServer401ResponseBody(http);
        return http.build(); 
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.addAllowedOrigin("https://finance-app-frontend-production-7ab9.up.railway.app");
//        configuration.addAllowedMethod("*");
        configuration.setAllowedMethods(Arrays.asList("GET","POST", "PUT", "DELETE", "PATCH"));
        configuration.addAllowedHeader("*");
        configuration.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource source = new
                UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }


}


When I tested the APIs in postman, they worked for all APIs except for the APIs with /api/goals/** (Not sure why I get a 403 error) Below are examples of the controllers

@CrossOrigin("https://finance-app-frontend-production-7ab9.up.railway.app")
@RestController
@RequestMapping("/api/expenses")
public class ExpenseController {
    private ExpenseService expenseService;

    @Autowired
    public ExpenseController(ExpenseService expenseService) {
        this.expenseService = expenseService;
    }

    @PostMapping("/add")
    public void addExpense(@RequestHeader(value="Authorization") String token,
                           @RequestBody AddExpenseRequest addExpenseRequest) throws Exception {
        String userEmail = ExtractJWT.payloadJWTExtract(token, "\"sub\"");
        if (userEmail==null) {
            throw new Exception("User email is missing");
        }
        expenseService.addExpense(userEmail, addExpenseRequest);
    }
}

and

@CrossOrigin("https://finance-app-frontend-production-7ab9.up.railway.app")
@RestController
@RequestMapping("/api/goals")
public class GoalController {
    private GoalService goalService;

    @Autowired
    public GoalController(GoalService goalService) {
        this.goalService = goalService;
    }

    @PostMapping("/add")
    public void addGoal(@RequestHeader(value = "Authorization") String token,
                        @RequestBody AddGoalRequest addGoalRequest) throws Exception {
        String userEmail = ExtractJWT.payloadJWTExtract(token, "\"sub\"");
        if (userEmail == null) {
            throw new Exception("User email is missing");
        }
         goalService.addGoal(userEmail,addGoalRequest);
    }
}


enter image description here

Frontend: enter image description here REACT_APP_API=https://finance-app-production-8d91.up.railway.app/api (I set this variable in variables in Railway)

Appreciate my help or ideas, thanks!

0

There are 0 best solutions below