Rust actix-web框架跨域请求配置

full actix cors set-up

在做静态博客评论系统时使用的是与主站www.qttc.net不同的域cume.qttc.net,这会造成一个跨域问题。在浏览器下使用XML Http Request或者fetch发出一个HTTP请求,假如这个HTTP的协议、主机名或者端口任意一个与当前网页地址有不一致时,为了安全浏览器会限制响应结果,通常这类问题就是所谓的跨域问题。

解决跨域问题的方式有很多,比如jsonpiframe等等。但在这里,我使用HTTP协议里约定的字段来解决这个问题,这也是最干净完美的解决方案。为了处理有跨域请求的特殊场景,HTTP协议里有一个特殊的响应头字段Access-Control-Allow-Origin,意思允许访问的Origin,值可以是通配符*,允许所有,或者写上一个具体的Origin值。

actix-web里, 我们需要配合actix_cors来处理关于跨域请求的配置,以下是一个例子

Cargo.toml

[package]
name = "actix-web-cors"
version = "1.0.0"
authors = ["Nicholas <lizhongit@gmail.com>"]
edition = "2018"

[dependencies]
actix-rt = "1.0.0"
actix-web = "2.0.0"
actix-cors = "0.2.0"
futures = "0.3"

main.rs

use actix_cors::Cors;
use actix_web::{web, App, HttpServer, Responder};

async fn index() -> impl Responder {
  "Hi, This is CORS request result\r\n"
}

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
  HttpServer::new(move || {
    App::new()
      .wrap(
        Cors::new()
          .allowed_origin("http://www.qttc.net")
          .allowed_methods(vec!["GET"])
          .max_age(3600)
          .finish(),
      )
      .route("/resource", web::get().to(index))
  })
  .bind("127.0.0.1:8000")?
  .run()
  .await
}

测试一下

$ curl -iv -H 'Origin: http://www.qttc.net' 127.0.0.1:8000/resource
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
> GET /resource HTTP/1.1
> Host: 127.0.0.1:8000
> User-Agent: curl/7.64.1
> Accept: */*
> Origin: http://www.qttc.net
> 
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< content-length: 33
content-length: 33
< vary: Origin
vary: Origin
< content-type: text/plain; charset=utf-8
content-type: text/plain; charset=utf-8
< access-control-allow-origin: http://www.qttc.net
access-control-allow-origin: http://www.qttc.net
< date: Wed, 03 Jun 2020 09:02:47 GMT
date: Wed, 03 Jun 2020 09:02:47 GMT

< 
Hi, This is CORS request result
* Connection #0 to host 127.0.0.1 left intact
* Closing connection 0

如果我们把http换成https看看结果

$ curl -iv -H 'Origin: https://www.qttc.net' 127.0.0.1:8000/resource
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
> GET /resource HTTP/1.1
> Host: 127.0.0.1:8000
> User-Agent: curl/7.64.1
> Accept: */*
> Origin: https://www.qttc.net
> 
< HTTP/1.1 400 Bad Request
HTTP/1.1 400 Bad Request
< content-length: 42
content-length: 42
< date: Wed, 03 Jun 2020 09:34:50 GMT
date: Wed, 03 Jun 2020 09:34:50 GMT

< 
* Connection #0 to host 127.0.0.1 left intact
Origin is not allowed to make this request* Closing connection 0

400出错了,提示

Origin is not allowed to make this request

不允许的Origin请求,http://www.qttc.nethttps://www.qttc.net被视为两个不同的Origin,所以如果要支持多个Origin就需要调用多次allowed_origin这个API增加

allowed_origin("http://www.qttc.net")
allowed_origin("https://www.qttc.net")

如果你需要允许所有的Origin,也就是不做限制的话,那么使用*号做通配符

allowed_origin("*")

通常来说不建议这么干

分享

TITLE: Rust actix-web框架跨域请求配置

LINK: https://www.qttc.net/528-actix-cors-setup-in-rust.html

NOTE: 原创内容,转载请注明出自琼台博客