Axum router rejecting CORS OPTIONS preflight with 405 even with CorsLayer
Asked Answered
G

2

9

Before a fetch is sent, the browser will send a request method OPTIONS to confirm that the API will accept the request from a script with a particular origin.

Chrome shows that the my Axum server is rejecting my client's request with 405. My router looks something like this:

let app = Router::new()
    .layer(TraceLayer::new_for_http())
    .layer(CorsLayer::permissive())
    .route("/api", post(server));

Router::layer says All requests to the router will be processed by the layer’s corresponding middleware. but I'm not sure its doing its job.

Garbo answered 26/8, 2022 at 8:59 Comment(0)
G
14

The .layer() function is a builder so returns a new Router, with the inner routers wrapped. The route /api will be tested first and be rejected 405 because only request method POST is supported - not OPTIONS.

In summary, you need your CorsLayer "outside" your route so it can answer OPTIONS requests.

Note the example in the documentation:

// All requests to `first_handler` and `second_handler` will be sent through
// `ConcurrencyLimit`
let app = Router::new().route("/", get(first_handler))
    .route("/foo", get(second_handler))
    .layer(ConcurrencyLimitLayer::new(64))
    // Request to `GET /bar` will go directly to `third_handler` and
    // wont be sent through `ConcurrencyLimit`
    .route("/bar", get(third_handler));

By the way, your TraceLayer is not tracing your API calls for the same reason!

Try this, and you'll see the OPTIONS request logged, and the POST should hit your server:

let app = Router::new()
    .route("/api", post(server))
    .layer(CorsLayer::permissive())
    .layer(TraceLayer::new_for_http());
Garbo answered 26/8, 2022 at 8:59 Comment(1)
use tower_http::cors::CorsLayer; use tower_http::trace::TraceLayer;Richel
A
2

Thanks, that solved the cross origin issue for Chrome

let app = Router::new()
    .route("/api", post(server))
    .layer(CorsLayer::permissive()) <----- PUT IT HERE
    .layer(TraceLayer::new_for_http());
Ahmadahmar answered 15/8, 2023 at 2:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.