rocket-FromRequest-cookie-login
1.具体逻辑流程
st=>start: 登陆
cond=>condition: 验证cookie是否存在 Yes or No?
op1=>operation: 提交用户信息
op2=>operation: 把用户id加密储存在cookie
op3=>operation: 计算位移
op4=>operation: 模拟人工滑动
e=>end: 管理后台
st->cond->op1->op2->e
cond(no)->op1
cond(yes)->e
2.FromRequest功能
原文介绍:A request guard is a type that represents an arbitrary validation policy. The validation policy is implemented through FromRequest. In other words, every type that implements FromRequest is a request guard.
Request guards appear as inputs to handlers. An arbitrary number of request guards can appear as arguments in a route handler. Rocket will automatically invoke the FromRequest implementation for request guards before calling the handler. Rocket only dispatches requests to a handler when all of its guards pass.
我们可以通过FromRequest在http请求之前进行操作,包括验证cookie,类似于Flask中路由函数实现的 @login_required 装饰。
3.具体代码
auth.rs
/*
权限验证工具,验证是否登陆;
利用FromRequest请求守卫,获取cookie的login_status;
*/
use rocket::{request::{FromRequest, self, Outcome}, Request, http::Status};
use serde::Deserialize;
#[derive(Debug, Clone, Deserialize)]
pub struct UserAuth{
permissions: String
}
#[rocket::async_trait]
impl<'r> FromRequest<'r> for UserAuth {
type Error = ();
async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
let cookies = req.cookies();
let cookie_value = cookies.get_private("login_user_id");
let status = match cookie_value {
Some(_) => true,
None => false,
};
if status {
return Outcome::Success(UserAuth{ permissions:String::from("admin") }) ;
}else {
return Outcome::Failure((Status::Unauthorized,()));
}
}
}
login.rs
use crate::models::user::User;
use crate::utils::response::HandleResponse;
use rocket::http::{Cookie, CookieJar};
use rocket::response::Redirect;
use rocket::route;
use rocket::serde::json::Json;
use rocket::serde::json::Value;
use rocket_dyn_templates::Template;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[route(GET, uri = "/login")]
pub async fn index(cookies: &CookieJar<'_>) -> HandleResponse {
let mut context = HashMap::new();
let login = cookies.get_private("login_user_id");
let login_status = match login {
Some(_) => true,
None => false,
};
context.insert("users", "users");
if login_status {
return HandleResponse::Redirect(Redirect::to("/admin/dashboard"));
} else {
return HandleResponse::Template(Template::render("content/login", context));
};
}
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct LoginUser {
mail: String,
password: String,
remember: bool,
}
#[route(POST, uri = "/login", data = "<form_data>")]
pub async fn post(cookies: &CookieJar<'_>, form_data: Json<LoginUser>) -> Value {
let user_data = form_data.into_inner();
let info = User::login_blog(&user_data.mail, &user_data.password).await;
let login = info.get("status").clone().unwrap().as_str().unwrap();
if login == "success" {
let user = User::get_user_by_email(&user_data.mail).await;
let mut ck = Cookie::new("login_user_id", user.id.unwrap().to_string());
if !user_data.remember {
ck.set_expires(None);
};
cookies.add_private(ck);
};
return info;
}
admin.rs
#[get("/dashboard")]
pub async fn index( _user_auth: UserAuth, ) -> Template {
/*
具体逻辑代码,管理员
*/
let template = Template::render("admin/blog-dashboard", &context);
template
}
最后修改: 2022-08-07T09:36:12
版权声明:署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)
comment 评论