我需要验证用户是否有权访问某些路线。我已经创建了 3 个“范围”(访客、身份验证用户、管理员),现在我不知道如何检查用户是否可以访问这些路由。
我正在尝试实现 auth-middleware,这个中间件应该检查用户是否有正确的 cookie 或令牌。(我可以从请求标头中打印出一个 cookie),但我不知道如何导入、使用 actix_identity 以及如何访问此中间件中的 id 参数。
我相信我的问题不仅与 Actix-identity 有关,而且我无法在中间件内部传递参数。
#[actix_rt::main]
async fn main() -> std::io::Result<()> {
let cookie_key = conf.server.key;
// Register http routes
let mut server = HttpServer::new(move || {
App::new()
// Enable logger
.wrap(Logger::default())
.wrap(IdentityService::new(
CookieIdentityPolicy::new(cookie_key.as_bytes())
.name("auth-cookie")
.path("/")
.secure(false),
))
//limit the maximum amount of data that server will accept
.data(web::JsonConfig::default().limit(4096))
//normal routes
.service(web::resource("/").route(web::get().to(status)))
// .configure(routes)
.service(
web::scope("/api")
// guest endpoints
.service(web::resource("/user_login").route(web::post().to(login)))
.service(web::resource("/user_logout").route(web::post().to(logout)))
// admin endpoints
.service(
web::scope("/admin")
// .wrap(AdminAuthMiddleware)
.service(
web::resource("/create_admin").route(web::post().to(create_admin)), …Run Code Online (Sandbox Code Playgroud) 在一个单独的演员向另一个演员发送消息的情况下.
我在官方文档中找不到任何相关内容.
我的客户通过Authorization标头中的令牌进行授权,每个请求都需要检查该令牌。如果没有这个头或者找不到对应的用户,我想返回HTTP代码Unauthorized,否则我想正常处理请求。
目前我有很多重复的代码,因为我正在每个请求处理程序中检查这个标头。该Actix的文档中的第一段表明,它是可能的halt request processing to return a response early。如何做到这一点?
由于我还没有找到实现此行为的示例,因此我尝试提出自己的中间件函数,但无法编译。
为了克服返回两种不同类型(ServiceResponse和Map)的问题,我已经对返回值进行了装箱,因此在如何有条件地返回不同类型的期货?不是问题。更重要的是,我不知道哪些类型具有哪些特征实现需要作为此wrap_fn函数的返回值。我现在拥有的那些不起作用。
App::new()
.wrap(Cors::new().allowed_origin("http://localhost:8080"))
.register_data(state.clone())
.service(
web::scope("/routing")
.wrap_fn(|req, srv| {
let unauth: Box<dyn IntoFuture<Item = ServiceResponse>> = Box::new(ServiceResponse::new(req.into_parts().0, HttpResponse::Unauthorized().finish()));
let auth_header = req.headers().get("Authorization");
match auth_header {
None => unauth,
Some(value) => {
let token = value.to_str().unwrap();
let mut users = state.users.lock().unwrap();
let user_state = users.iter_mut().find(|x| x.auth.token == token);
match user_state {
None => unauth,
Some(user) …Run Code Online (Sandbox Code Playgroud) 目前我的主要功能,服务器启动的地方看起来像这样
#[actix_rt::main]
async fn main() -> std::io::Result<()> {
let address = "0.0.0.0:3000";
HttpServer::new(move || {
let app_state = {...some state};
App::new()
.data(app_state)
.wrap(middleware::Logger::default())
.service(network_api::init_service())
})
.bind(address)?
.run()
.await
}
Run Code Online (Sandbox Code Playgroud)
服务器启动后,我想运行一个(异步)函数,以向另一台服务器发出请求,并且该服务器应该向刚刚启动并运行的该服务器发出另一个请求。
不确定我在文档中是否看到任何提及仅在服务器启动时运行一次的回调函数的内容。
例如,也许让它run()发挥作用,像这样:
run(|| {
// server started now perform some request or whatever
Client::new().post(&url).json(json_stuff).send().await
})
Run Code Online (Sandbox Code Playgroud)
编辑 我想我已经解决了,当我可以回答我自己的问题时会发布答案
我尝试更新到 actix_rt 2.0.2,但一直收到以下错误:
线程“main”因“系统未运行”而恐慌
我的最小例子在这里
use actix_rt;
use actix_web::{HttpServer, App, HttpResponse};
async fn hello() -> HttpResponse {
HttpResponse::Ok().finish()
}
#[actix_rt::main]
async fn main() -> std::io::Result<()> {
let server = HttpServer::new(move || {
App::new().route("/", actix_web::web::get().to(hello))
});
server.bind("127.0.0.1:8080")?.run().await
}
Run Code Online (Sandbox Code Playgroud)
货物.toml
[package]
name = "my_app"
version = "2.2.0"
authors = ["me"]
edition = "2018"
[dependencies]
actix = "0.10"
actix-web = { version = "3.3.2", default-features = false }
actix-rt = "2.0.2"
Run Code Online (Sandbox Code Playgroud)
我假设它一定是actix板条箱之间的某些版本不兼容。是否有版本号的组合或我缺少的一些明显的东西来让它们一起工作?
我需要 actix_rt 2.0.x 以便我可以与Criterion集成
提前感谢您的任何见解。
干杯!
这是从 Actix-Web 请求中获取内容类型标头的唯一可能性吗?这必须检查标题是否可用或是否to_str失败...
let req: actix_web::HttpRequest;
let content_type: &str = req
.request()
.headers()
.get(actix_web::http::header::CONTENT_TYPE)
.unwrap()
.to_str()
.unwrap();
Run Code Online (Sandbox Code Playgroud) 如何使用actix-web从以下URL 解析name和color参数?
http://example.com/path/to/page?name=ferret&color=purple
Run Code Online (Sandbox Code Playgroud)
我想我的路径应该是/path/to/page,然后当我尝试查询时name收到一个空字符串(req.match_info().query("name")where req: &HttpRequest)。
我发现的唯一文档是关于匹配名称的(例如,如果路径/people/{page}/匹配/people/123/,则这样匹配,page = 123但这不是我想要的)。
我正在使用 actix-web 构建 REST API。如何配置 CORS 以接受来自任何来源的请求?
Cors::new() // <- Construct CORS middleware builder
.allowed_origin("localhost:8081")
.allowed_methods(vec!["GET", "POST"])
.allowed_headers(vec![http::header::AUTHORIZATION, http::header::ACCEPT])
.allowed_header(http::header::CONTENT_TYPE)
.max_age(3600)
Run Code Online (Sandbox Code Playgroud)
上面的代码在 网络上工作localhost:8081,但不能从0.0.0.0:8081或127.0.0.1:8081。我试图"*"允许所有,但它不起作用。如何允许所有或至少允许特定来源然后传递多个 URL?
我正在使用 Actix 框架来创建一个简单的服务器,并且我已经使用一个简单的 HTML 前端实现了文件上传。
use actix_web::web::Data;
use actix_web::{middleware, web, App, HttpResponse, HttpServer};
use std::cell::Cell;
// file upload functions, the same as you can find it under the
// actix web documentation:
// https://github.com/actix/examples/blob/master/multipart/src/main.rs :
mod upload;
fn index() -> HttpResponse {
let html = r#"<html>
<head><title>Upload Test</title></head>
<body>
<form target="/" method="post" enctype="multipart/form-data">
<input type="file" name="file"/>
<input type="submit" value="Submit"></button>
</form>
</body>
</html>"#;
HttpResponse::Ok().body(html)
}
#[derive(Clone)]
pub struct AppState {
counter: Cell<usize>,
}
impl AppState {
fn new() -> Result<Self, Error> …Run Code Online (Sandbox Code Playgroud) 我正在使用 Rust 和 actix_web 构建 Web API 服务。
我想测试一条路线并检查收到的响应正文是否符合我的预期。但是我正在努力将接收到的正文ResponseBody<Body>转换为 JSON 或 BSON。被调用的路由实际上返回application/json.
let mut app = test::init_service(App::new()
.data(AppState { database: db.clone() })
.route("/recipes/{id}", web::post().to(add_one_recipe))
).await;
let payload = create_one_recipe().as_document().unwrap().clone();
let req = test::TestRequest::post()
.set_json(&payload).uri("/recipes/new").to_request();
let mut resp = test::call_service(&mut app, req).await;
let body: ResponseBody<Body> = resp.take_body(); // Here I want the body as Binary, String, JSON, or BSON. The response is actually application/json.
Run Code Online (Sandbox Code Playgroud)