身份验证 #
JWT 认证 #
添加依赖 #
toml
[dependencies]
jsonwebtoken = "9"
serde = { version = "1", features = ["derive"] }
chrono = { version = "0.4", features = ["serde"] }
JWT 配置 #
rust
use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, Header, Validation};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
pub sub: String,
pub exp: usize,
pub iat: usize,
}
pub struct JwtConfig {
pub secret: String,
pub expiration: i64,
}
impl JwtConfig {
pub fn new(secret: String, expiration: i64) -> Self {
Self { secret, expiration }
}
pub fn generate_token(&self, user_id: &str) -> Result<String, jsonwebtoken::errors::Error> {
let now = chrono::Utc::now();
let exp = now + chrono::Duration::seconds(self.expiration);
let claims = Claims {
sub: user_id.to_string(),
exp: exp.timestamp() as usize,
iat: now.timestamp() as usize,
};
encode(
&Header::default(),
&claims,
&EncodingKey::from_secret(self.secret.as_bytes()),
)
}
pub fn validate_token(&self, token: &str) -> Result<Claims, jsonwebtoken::errors::Error> {
decode::<Claims>(
token,
&DecodingKey::from_secret(self.secret.as_bytes()),
&Validation::new(Algorithm::HS256),
)
.map(|data| data.claims)
}
}
认证中间件 #
rust
use actix_web::{dev::Payload, Error, FromRequest, HttpRequest};
use futures::future::{ready, Ready};
pub struct AuthUser {
pub user_id: String,
}
impl FromRequest for AuthUser {
type Error = Error;
type Future = Ready<Result<Self, Self::Error>>;
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
let jwt_config = req.app_data::<web::Data<JwtConfig>>().unwrap();
let auth_header = req.headers().get("Authorization");
match auth_header {
Some(header_value) => {
let token = header_value
.to_str()
.unwrap_or("")
.strip_prefix("Bearer ")
.unwrap_or("");
match jwt_config.validate_token(token) {
Ok(claims) => ready(Ok(AuthUser {
user_id: claims.sub,
})),
Err(_) => ready(Err(actix_web::error::ErrorUnauthorized("Invalid token"))),
}
}
None => ready(Err(actix_web::error::ErrorUnauthorized("Missing token"))),
}
}
}
使用认证 #
rust
#[actix_web::get("/protected")]
async fn protected(user: AuthUser) -> impl Responder {
web::Json(serde_json::json!({
"user_id": user.user_id,
"message": "Access granted"
}))
}
登录接口 #
rust
#[derive(Deserialize)]
struct LoginRequest {
username: String,
password: String,
}
#[actix_web::post("/login")]
async fn login(
body: web::Json<LoginRequest>,
jwt_config: web::Data<JwtConfig>,
) -> impl Responder {
if body.username == "admin" && body.password == "secret" {
match jwt_config.generate_token("user_123") {
Ok(token) => HttpResponse::Ok().json(serde_json::json!({
"token": token
})),
Err(e) => HttpResponse::InternalServerError()
.json(serde_json::json!({ "error": e.to_string() })),
}
} else {
HttpResponse::Unauthorized().json(serde_json::json!({
"error": "Invalid credentials"
}))
}
}
下一步 #
继续学习 授权控制,了解权限管理!
最后更新:2026-03-29