Rust中的授权与身份验证:完整指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Rust中的授权与身份验证:开发者完整指南



Rust是一种系统编程语言,在构建高负载且安全的Web服务方面越来越受欢迎。然而,由于Rust严格的类型系统和缺乏内置解决方案,在Rust中实现身份验证(身份验证)和授权(权限验证)需要特殊的方法。在本文中,我们将介绍关键的库和实际示例。



为什么选择Rust进行身份验证?

安全性是Rust的首要任务。编译器可防止内存泄漏、数据竞争以及C/C++中常见的许多漏洞。然而,手动实现身份验证可能会导致错误,因此社区创建了几个成熟的库。



Rust中用于身份验证的主要库



1. actix-web-httpauth — 用于Web框架Actix-web

在Actix-web生态系统中实现HTTP身份验证(Basic、Bearer、Digest)最流行的库。



2. jsonwebtoken — 处理JWT

Rust中JSON Web Tokens (JWT)的完整实现。支持RS256、HS256、ES256等算法。



3. bcrypt — 密码哈希

使用bcrypt算法进行密码哈希的可靠库,支持自动生成盐值。



4. argon2 — 现代哈希

如果觉得bcrypt过时,可以使用Argon2——密码哈希竞赛的获胜者。



5. tower-http — 授权中间件

允许在任何基于Tower的HTTP服务器中创建可重用的中间件来检查访问权限。



实践示例:在Actix-web中通过JWT进行身份验证

我们来看一个包含注册和登录的最小服务器示例。首先,在Cargo.toml中添加依赖项:

[dependencies]actix-web = "4"actix-web-httpauth = "0.8"jsonwebtoken = "9"bcrypt = "0.15"serde = { version = "1", features = ["derive"] }tokio = { version = "1", features = ["full"] }


现在编写用户结构体以及创建/验证JWT的函数:

use actix_web::{web, App, HttpServer, HttpResponse, HttpRequest};use actix_web_httpauth::extractors::bearer::BearerAuth;use jsonwebtoken::{encode, decode, Header, Validation, EncodingKey, DecodingKey};use bcrypt::{hash, verify, DEFAULT_COST};use serde::{Serialize, Deserialize};

#[derive(Debug, Serialize, Deserialize)]struct Claims { sub: String, // 用户邮箱 exp: usize, // 令牌过期时间}

#[derive(Debug, Serialize, Deserialize)]struct User { email: String, password_hash: String,}

// 用户存储(实际应用中为数据库)static USERS: once_cell::sync::Lazy<std::sync::Mutex<Vec<User>>> = once_cell::sync::Lazy::new(|| std::sync::Mutex::new(vec![]));

async fn register(info: web::Json<UserInput>) -> HttpResponse { let hashed = hash(&info.password, DEFAULT_COST).unwrap(); let user = User { email: info.email.clone(), password_hash: hashed, }; USERS.lock().unwrap().push(user); HttpResponse::Ok().json("User registered")}

async fn login(info: web::Json<UserInput>) -> HttpResponse { let users = USERS.lock().unwrap(); if let Some(user) = users.iter().find(|u| u.email == info.email) { if verify(&info.password, &user.password_hash).unwrap() { let claims = Claims { sub: info.email.clone(), exp: 10000000000, }; let token = encode( &Header::default(), &claims, &EncodingKey::from_secret(b"secret_key"), ).unwrap(); return HttpResponse::Ok().json(token); } } HttpResponse::Unauthori

推荐