Rust用户信息
用户信息getInfo
🍎routes.rs
在入口文件之中导入对应模块,上面我们已经导入了,然后在这里我们编写我们想要的对应接口
注册路由,集中管理接口路径映射
javascript
src\modules\user\routes.rs
pub fn config(cfg: &mut web::ServiceConfig) {
cfg.route("/getInfo", web::get().to(crate::modules::user::handlers::get_info));
}
🍎简单写一个关于用户的逻辑测试接口
javascript
src\modules\user\handlers.rs
pub async fn get_info() -> HttpResponse {
HttpResponse::Ok().json(ApiResponse {
code: 200,
msg: "获取用户信息成功",
data: None::<()>,
})
}
🍎访问测试
这个时候打开我们的接口,我们就可以发现
javascript
http://127.0.0.1:8888/api/getInfo
//这个时候的返回信息
{"code":200,"msg":"获取用户信息成功"}
登录返回token
🍎Cargo.toml
添加依赖
我们缺少用于处理 JWT 的 jsonwebtoken
库和用于处理时间的 chrono
库,将这两个依赖项添加到文件中
javascript
jsonwebtoken = "9"
chrono = { version = "0.4", features = ["serde"] }
🍎依赖引入
添加依赖以后重新运行,引入对用部分的依赖
javascript
// token部分
use jsonwebtoken::{encode, decode, Header, Validation, EncodingKey, DecodingKey};
use chrono::{Utc, Duration};
use serde::{Serialize, Deserialize};
🍎填写密钥定义登录返回数据类型
javascript
// token部分
#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
pub username: String,
pub exp: usize,
}
#[derive(Serialize)]
pub struct LoginResponse {
pub token: String,
pub code: i32,
pub msg: &'static str,
}
const JWT_SECRET: &[u8] = b"your_secret_key";
🍎登录接口之中添加token
这里我们完善一下我们登录方法login_users
方法
javascript
if is_valid {
// 生成 token
let expiration = Utc::now()
.checked_add_signed(Duration::days(1))
.expect("valid timestamp")
.timestamp();
let claims = Claims {
username: user.username.clone(),
exp: expiration as usize,
};
let token = encode(&Header::default(), &claims, &EncodingKey::from_secret(JWT_SECRET))
.unwrap();
HttpResponse::Ok().json(LoginResponse {
code: 200,
msg: "登录成功",
token: token,
})
// HttpResponse::Ok().json(ApiResponse {
// code: 200,
// msg: "登录成功",
// data: None::<()>,
// })
} else {
HttpResponse::Ok().json(ApiResponse {
code: 400,
msg: "用户名或密码错误",
data: None::<()>,
})
}
查看我们返回的数据,这个时候token已经给我们返回了
javascript
{
"token": "eyJ0Ixxxx",
"code": 200,
"msg": "登录成功"
}
token认证换取信息
🍎get_info
接口返回我们的信息
javascript
pub async fn get_info(req: HttpRequest, pool: web::Data<MySqlPool>) -> HttpResponse {
// 从 header 获取 token
let token = match req.headers().get("Authorization") {
Some(t) => t.to_str().unwrap_or("").replace("Bearer ", ""),
None => return HttpResponse::Unauthorized().json(ApiResponse {
code: 401,
msg: "未提供Token",
data: None::<()>,
}),
};
// 校验 token
let token_data = match decode::<Claims>(
&token,
&DecodingKey::from_secret(JWT_SECRET),
&Validation::default(),
) {
Ok(data) => data,
Err(_) => return HttpResponse::Unauthorized().json(ApiResponse {
code: 401,
msg: "Token无效或已过期",
data: None::<()>,
}),
};
// 根据 token 里的 username 查询用户信息
let user = sqlx::query_as::<_, User>("SELECT * FROM sys_user WHERE username = ?")
.bind(&token_data.claims.username)
.fetch_one(pool.get_ref())
.await;
match user {
Ok(u) => HttpResponse::Ok().json(ApiResponse {
code: 200,
msg: "获取用户信息成功",
data: Some(u),
}),
Err(_) => HttpResponse::InternalServerError().json(ApiResponse {
code: 500,
msg: "用户不存在",
data: None::<()>,
}),
}
}
测试一下,这个时候可以看到我们的信息
javascript
{
"code": 200,
"msg": "获取用户信息成功",
"data": {
"username": "adin",
"password": "$2b$10$lIa70GjuW6qi09u",
"age": null,
"name": null,
"sex": null,
"address": null,
"state": null,
"phone": "adin",
"avatar": null,
"user_height": null,
"user_weight": null,
"disease": null
}
}
这个时候token换取我们用户信息的接口就已经好了