如何在Rocket.rs中正确编写req守卫?

问题描述 投票:0回答:1

我正在尝试编写请求保护,它将返回

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
在哪里?

rust rust-rocket
1个回答
0
投票

工作代码

不幸的是,我在这里找到了 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)
      }

    }


  }



}
© www.soinside.com 2019 - 2024. All rights reserved.