actix / actix-web

Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust.
https://actix.rs
Apache License 2.0
21.6k stars 1.67k forks source link

How to define a custom Cors middleware? #725

Closed GopherJ closed 5 years ago

GopherJ commented 5 years ago

Hello, I am new to rust and actix-web, I'd like to define a custom Cors middleware but found the OPTIONS preflight request doesn't have the headers which should be added when pasing this middleware.

Here is the middleware's code:

use actix_web::{
    http::{header, Method},
    middleware::{Middleware, Response, Started},
    HttpRequest, HttpResponse, Result,
};

use crate::CONFIG;

pub struct Cors;

impl<S> Middleware<S> for Cors {
    fn response(&self, req: &HttpRequest<S>, resp: HttpResponse) -> Result<Response> {
        // Cross-Origin Requests
        println!("{:?}", req.headers().get("Origin"));
        if let Some(origin) = req.headers().get("Origin") {
            let mut http_response_builder = resp.into_builder();

            http_response_builder
                .header(
                    header::ACCESS_CONTROL_ALLOW_ORIGIN,
                    origin.to_str().unwrap_or("*"),
                )
                .header(header::ACCESS_CONTROL_ALLOW_CREDENTIALS, "true")
                .header(
                    header::ACCESS_CONTROL_ALLOW_HEADERS,
                    CONFIG.cors.access_control_allow_headers.as_str(),
                );

            if req.method() == Method::OPTIONS {
                http_response_builder
                    .header(
                        header::ACCESS_CONTROL_ALLOW_METHODS,
                        CONFIG.cors.access_control_allow_methods.as_str(),
                    )
                    .header(
                        header::ACCESS_CONTROL_MAX_AGE,
                        CONFIG.cors.access_control_max_age.to_string(),
                    );
            }

            Ok(Response::Done(http_response_builder.finish()))
        } else {
            Ok(Response::Done(resp))
        }
    }
}

Here is the config file:

...
[cors]
access-control-max-age = 86400
access-control-allow-methods = "PUT,DELETE,POST,GET"
access-control-allow-headers = "Content-Type,Authorization"

Here is the OPTIONS request Screenshot from 2019-03-14 04-22-34

DoumanAsh commented 5 years ago

You could use existing CORS middleware code as reference https://github.com/actix/actix-web/blob/master/src/middleware/cors.rs

GopherJ commented 5 years ago

@DoumanAsh hello, I would like the Access-Control-Allow-Origin always be the value of Origin field in request header, but I didn't find a way to do this using actix-web's cors middleware.

Could you please check if I did a mistake in my code or give me some information on how to do this using Actix-web's cors middleware. Thanks!