我正在尝试编写请求保护,它将返回
user_id: String
或只是用 Status::Unauthorized
终止请求
use rocket::async_trait;
use rocket::http::Status;
use rocket::outcome::IntoOutcome;
use rocket::request::{FromRequest, Outcome, Request};
use mongodb::bson::doc;
// modules
use crate::user_module::user_model::UserModel;
use crate::DB;
struct Auth {}
#[async_trait]
impl<'r> FromRequest<'r> for Auth {
type Error = ();
async fn from_request(req: &'r Request<'_>) -> Outcome<String, ()> {
let db = DB.get().unwrap();
let users_collection = db.collection::<UserModel>("users");
req.cookies()
.get_private("user_id")
.and_then(|cookie| cookie.value().parse::<String>().ok())
.or_forward(Status::Unauthorized)
}
}
问题是......它总是给我一个错误,不管我改变什么
现在的问题是
method `from_request` has an incompatible type for trait
expected signature `fn(&'r rocket::Request<'_>) -> Pin<Box<(dyn std::future::Future<Output = Outcome<guards::Auth::Auth, (Status, ()), Status>> + std::marker::Send + 'async_trait)>>`
found signature `fn(&'r rocket::Request<'_>) -> Pin<Box<(dyn std::future::Future<Output = Outcome<std::string::String, (Status, ()), Status>> + std::marker::Send + 'async_trait)>>`
我不知道这是关于什么的
我找到的指南是...我不知道不完整吗?
struct
在哪里?
工作代码
不幸的是,我在这里找到了 0 个如何强制 Rocket 解析私有 cookie 的信息,所以有一个无需解析 cookie 值的工作代码的解决方案
use rocket::request::{Request, FromRequest, Outcome};
use rocket::outcome::IntoOutcome;
use rocket::{async_trait};
use rocket::http::{Status, Cookie};
use mongodb::bson::doc;
// modules
use crate::DB;
use crate::user_module::user_model::UserModel;
pub struct Auth {
pub user_id: String,
}
#[async_trait]
impl<'r> FromRequest<'r> for Auth {
type Error = ();
async fn from_request(req: &'r Request<'_>) -> Outcome<Self, ()> {
let db = DB.get().unwrap();
let users_collection = db.collection::<UserModel>("users");
let a_cookie = req.cookies().get("a-token");
// if no such cookie
if a_cookie.is_none() {
return Outcome::Forward(Status::Unauthorized);
}
// if cookie
match a_cookie.unwrap().value().parse::<String>() {
Ok(user_id) => {
let user_id_verif = /* verify user_id (cuz it was encrypted) */
let user: Option<UserModel> = users_collection.find_one(doc! {"user_id": &user_id_verif}, None).await.expect("Error connecting to DB");
if user.is_none() {
// if no such user
Outcome::Forward(Status::Unauthorized)
} else {
Outcome::Success(Auth {user_id})
}
},
// if invalid
Err(_) => {
Outcome::Forward(Status::Unauthorized)
}
}
}
}