¿Cómo pasar una variable a actix-web guard () en Rust?
Sep 06 2020
#[actix_rt::main]
async fn main() -> std::io::Result<()> {
let token = env::var("TOKEN").expect("Set TOKEN");
HttpServer::new(|| {
App::new()
.wrap(middleware::Logger::default())
.service(
web::resource("/")
.guard(guard::Header("TOKEN", &token))
.route(web::post().to(index))
)
})
.bind("127.0.0.1:8080")?
.run()
.await
}
El error es:
error[E0597]: `token` does not live long enough
Lo vi .data()en los documentos de Actix, pero eso es para pasar variables dentro de las funciones de rutas.
UPD:
Si agrego "mover":
HttpServer::new(move || {
entonces solo cambia el error:
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
--> src/main.rs:50:58
|
50 | .guard(guard::Header("TOKEN", &token))
| ^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'_` as defined on the body at 42:21...
--> src/main.rs:42:21
|
42 | HttpServer::new(move || {
| ^^^^^^^
note: ...so that closure can access `token`
--> src/main.rs:50:58
|
50 | .guard(guard::Header("TOKEN", &token))
| ^^^^^^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that reference does not outlive borrowed content
--> src/main.rs:50:58
|
50 | .guard(guard::Header("TOKEN", &token))
| ^^^^^^
error: aborting due to previous error
Respuestas
Sergey Sep 06 2020 at 19:41
actix-web crea muchos hilos y cada trabajador (en cada hilo) debe obtener una copia de una variable. Entonces usando let token = token.clone();y move.
Después de eso, cada una de estas variables entra en fn_guardfuncionamiento. Así que una vez más move.
let token = env::var("TOKEN").expect("You must set TOKEN");
HttpServer::new(move || {
let token = token.clone();
App::new()
.wrap(middleware::Logger::default())
.service(
web::resource("/")
.guard(guard::fn_guard(
move |req| match req.headers().get("TOKEN") {
Some(value) => value == token.as_str(),
None => false,
}))
.route(web::post().to(index))
)
})
.bind("127.0.0.1:8080")?
.run()
.await
Esto funciona.
No puedo hacer que funcione solo con .guard(guard::Header("TOKEN", &token))