3

I'm implementing a ReactJs applications. I am using axios to invoke server side services built using Spring Boot. I need to send the header "Authorization: Bearer token-value". This is the client side code:

var options = {
    withCredentials: true,
    headers: {'Authorization': 'Bearer token-value'}
};
axios.post('http://localhost:9090/services/list', null, options)
    .then((data) => {
        console.log(data);
    })
    .catch((error) => {
        console.error(error);
    });

This is the Spring Boot controller:

@RestController
public class ServiceController {

    private static final String AUTHORIZATION_HEADER_NAME = "Authorization";
    private static final String BEARER = "Bearer ";

    private static String getToken(HttpServletRequest request) {
        String header = request.getHeader(AUTHORIZATION_HEADER_NAME);
        if (header == null || header.trim().equals("")) {
            return null;
        }
        header = header.trim();
        if (!header.startsWith(BEARER)) {
            return null;
        }
        return header.substring(BEARER.length()).trim();
    }

    @GetMapping
    @RequestMapping(value = "/services/list", produces = "application/json", method = RequestMethod.POST)
    public ResponseEntity<?> getTargets(HttpServletRequest request, HttpServletResponse response) {
        String token = getToken(request);
        if (token == null) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
        DTOObject obj = goForTheBusinessObject(token);
        return new ResponseEntity<>(obj, HttpStatus.OK);
    }
}

This is the CORS configuration

@Configuration
public class RestConfig {
    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("DELETE");
        config.addAllowedMethod("PUT");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

If I invoke the service using curl I got the expected response:

curl -X POST -H "Authorization: Bearer token-value" http://localhost:9090/services/list

If I invoke the service using post man, again I got the right answer.

But when I executed the ReactJS application, the server never receive the "Authorization" header.

Somebody help me please !!

1 Answer 1

1

You are facing CORS issues, Implement this class to resolve this-

@Component
public class CorsFilter  implements WebFilter  {

@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
    if (exchange != null) {
        exchange.getResponse().getHeaders().add("Access-Control-Allow-Origin", "*");
        exchange.getResponse().getHeaders().add("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, OPTIONS");
        exchange.getResponse().getHeaders().add("Access-Control-Allow-Headers",
                "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range");
        exchange.getResponse().getHeaders().add("Access-Control-Max-Age", "1728000");

        if (exchange.getRequest().getMethod() == HttpMethod.OPTIONS) {
            exchange.getResponse().getHeaders().add("Access-Control-Max-Age", "1728000");
            exchange.getResponse().setStatusCode(HttpStatus.NO_CONTENT);
            return Mono.empty();
        } else {
            exchange.getResponse().getHeaders().add("Access-Control-Expose-Headers", "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range");
            return chain.filter(exchange);
        }

    } else {
        return chain.filter(exchange);
    }

}
}

For more info on CORS visit this

Update: For scanning the component you can do following-

@ComponentScan(value = "com.pck", // cors filter package
    useDefaultFilters = false)
public class MainClass {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.
        run(MainClass.class, args);
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks Deen. I already implemented what you say. Now my problem is that Spring Boot is not finding the class. I wrote a debug message into the method filter(ServerWebExchange exchange, WebFilterChain chain) and I have added the name of the new class package to the scanners: @ComponentScan, @ServletComponentScanand as parameter of the annotation @SpringBootApplication, but the CORS are not being loaded for Spring Boot. Any suggestion?... Thanks again.
Have you tried this, @SpringBootApplication(scanBasePackages = { "com.pkg"})?
@RDV, I have updated the answer. Can you try out this and let me know if it's working?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.