-2

From react i call an actix api

async function richiesteFn() {
  try {
    const response = await fetch('https://exampleip/richieste', {
      method: 'GET',
      headers: {
        Authorization: sessionStorage.getItem('auth0_token'),
      },
    });
    const data = await response.json();
    // console.log(data);
    return data;
  } catch (error) {
    return error;
  }
}

here is the actix api

#[get("/richieste")]
async fn richieste_srvc(req: HttpRequest) -> HttpResponse {
    let authorization_present = req.headers().contains_key("Authorization");
    if authorization_present {
        let authorization = req.headers().get("Authorization").unwrap();
        let auth_str = authorization.to_str().unwrap();
        let validate_token_fn = validate_auth0_token(&auth_str);
        if validate_token_fn.is_err(){ 
            let error = validate_token_fn.unwrap_err();
            let err_str = format!("{{ \"Error\": \"{}\" }}", error);
            HttpResponse::Ok().body(err_str)
        } else {
            let str = mostra_richieste();
            if str.is_err() {
                let error = str.unwrap_err();
                let err_str = format!("{{ \"Error\": \"Errore nella lista richieste: {}\" }}", error);
                HttpResponse::Ok().content_type(ContentType::json()).body(err_str)
            } else {
                HttpResponse::Ok().content_type(ContentType::json()).body(str.unwrap())
            }
        }
    } else {
        let err_str = format!("{{ \"Error\": \"Authorization header not present\" }}");
        HttpResponse::Ok().content_type(ContentType::json()).body(err_str)
    }
}

here is actix start function

HttpServer::new(move || {
        let logger = Logger::default();
        let cors_allowed_origin = env::var("CORS_ALLOWED_ORIGIN").unwrap();
        let cors = Cors::default()
        .allowed_origin(&cors_allowed_origin);
        App::new()
            .wrap(logger)
            .wrap(cors)
            .service(login)
            .service(validate_token)
            .service(richieste_srvc)
    })

if i remove the code down here from the react js request the api works

, {
      method: 'GET',
      headers: {
        Authorization: sessionStorage.getItem('auth0_token'),
      },

and i tried adding the Access-Control-Allow-Origin in the actix respone but still same error.

here is the complete error:

Access to fetch at 'https://exampleip/richieste' from origin 'https://exampleip' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

GranBoh
  • 67
  • 8
  • What happens if you use [`Cors::permissive()`](https://docs.rs/actix-cors/latest/actix_cors/struct.Cors.html#method.permissive)? If this doesn't work we could rule out bad cors configuration as being the reason for your error. – Jonas Fassbender Mar 24 '23 at 16:10
  • @JonasFassbender Thank you with Cors::permissive() it works! what's the difference from Cors::default()? i also kept the .allowed_origin(&cors_allowed_origin); is thath ok? – GranBoh Mar 24 '23 at 16:21
  • `Cors::permissive()` allows every operation and every header from every origin, which is good for testing but you may not wish to that for your production system. On the contrary to `Cors::permissive()`, [`Cors::default()`](https://docs.rs/actix-cors/latest/actix_cors/struct.Cors.html#method.default) doesn't allow any operation or any header from any origin. You must enable methods, origin and headers yourself. Please try `Cors::default().allowed_origin(&cors_allowed_origin).allow_any_header().allow_any_method()` next and see if it still works. – Jonas Fassbender Mar 24 '23 at 16:34
  • @JonasFassbender yes it works like this, thank you for the exhaustive answer! Very nice – GranBoh Mar 27 '23 at 07:55
  • 1
    Glad I could help. I created an answer from my previous comment. Please note that I forgot to mention response headers in the comment, which may cause your CORS settings to break again if you want to set response headers. I've added the necessary step to enable all response headers in the answer. – Jonas Fassbender Mar 27 '23 at 08:28

1 Answers1

1

Answer created from this comment.

The problem was bad CORS configuration. actix_cors::Cors::default() creates "security paranoid" CORS settings, disallowing any headers, origin or methods. These restrictive settings must be explicitly overridden to create a usable CORS middleware.

let cors = Cors::default()
    .allowed_origin(&cors_allowed_origin);

still allows no headers, no methods and no response headers, causing the CORS error observed in the browser. All headers, all methods and all response headers can be allowed with the allow_any_header and allow_any_method and expose_any_header methods, respectively.

let cors = Cors::default()
    .allowed_origin(&cors_allowed_origin)
    .allow_any_header()
    .allow_any_method()
    .expose_any_header();

This should create a usable CORS middleware.

Note that, same as the origin setting, the settings for headers, methods and response headers can be further restricted to increase the security of your cross-origin requests.

Jonas Fassbender
  • 2,371
  • 1
  • 3
  • 19