NAC_Blockchain/_archive/nac-onboarding-system-legacy/src/handlers/auth.rs

151 lines
4.1 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// NAC资产一键上链系统 - 认证API处理器
use actix_web::{web, HttpResponse};
use serde::{Deserialize, Serialize};
use jsonwebtoken::{encode, EncodingKey, Header};
use bcrypt::{hash, verify, DEFAULT_COST};
use crate::database::DbPool;
use crate::error::Result;
use crate::models::User;
use crate::middleware::Claims;
use crate::response::ApiResponse;
/// 注册请求
#[derive(Debug, Deserialize)]
pub struct RegisterRequest {
pub username: String,
pub password: String,
pub email: String,
pub full_name: String,
}
/// 登录请求
#[derive(Debug, Deserialize)]
pub struct LoginRequest {
pub username: String,
pub password: String,
}
/// 登录响应
#[derive(Debug, Serialize)]
pub struct LoginResponse {
pub token: String,
pub user: UserInfo,
}
/// 用户信息
#[derive(Debug, Serialize)]
pub struct UserInfo {
pub id: String,
pub username: String,
pub email: String,
pub full_name: String,
pub role: String,
}
/// 注册
pub async fn register(
pool: web::Data<DbPool>,
req: web::Json<RegisterRequest>,
) -> Result<HttpResponse> {
log::info!("用户注册username = {}", req.username);
// 检查用户名是否已存在
if User::find_by_username(&pool, &req.username).await.is_ok() {
return Ok(HttpResponse::BadRequest().json(ApiResponse::<()>::error("用户名已存在")));
}
// 检查邮箱是否已存在
if User::find_by_email(&pool, &req.email).await.is_ok() {
return Ok(HttpResponse::BadRequest().json(ApiResponse::<()>::error("邮箱已存在")));
}
// 哈希密码
let password_hash = hash(&req.password, DEFAULT_COST)
.map_err(|e| crate::error::OnboardingError::Internal(format!("密码哈希失败: {}", e)))?;
// 创建用户
let user = User::create(
&pool,
&req.username,
&password_hash,
&req.email,
&req.full_name,
).await?;
log::info!("用户注册成功user_id = {}", user.id);
Ok(HttpResponse::Ok().json(ApiResponse::success(UserInfo {
id: user.id,
username: user.username,
email: user.email,
full_name: user.full_name,
role: user.role,
})))
}
/// 登录
pub async fn login(
pool: web::Data<DbPool>,
req: web::Json<LoginRequest>,
) -> Result<HttpResponse> {
log::info!("用户登录username = {}", req.username);
// 查找用户
let user = User::find_by_username(&pool, &req.username).await?;
// 验证密码
let valid = verify(&req.password, &user.password_hash)
.map_err(|e| crate::error::OnboardingError::Internal(format!("密码验证失败: {}", e)))?;
if !valid {
return Ok(HttpResponse::Unauthorized().json(ApiResponse::<()>::error("用户名或密码错误")));
}
// 生成JWT token
let jwt_secret = std::env::var("JWT_SECRET").unwrap_or_else(|_| "nac-secret-key".to_string());
let claims = Claims {
sub: user.id.clone(),
username: user.username.clone(),
role: user.role.clone(),
exp: (chrono::Utc::now() + chrono::Duration::days(7)).timestamp() as usize,
};
let token = encode(
&Header::default(),
&claims,
&EncodingKey::from_secret(jwt_secret.as_bytes()),
).map_err(|e| crate::error::OnboardingError::Internal(format!("Token生成失败: {}", e)))?;
log::info!("用户登录成功user_id = {}", user.id);
Ok(HttpResponse::Ok().json(ApiResponse::success(LoginResponse {
token,
user: UserInfo {
id: user.id,
username: user.username,
email: user.email,
full_name: user.full_name,
role: user.role,
},
})))
}
/// 获取当前用户信息
pub async fn me(
pool: web::Data<DbPool>,
claims: web::ReqData<Claims>,
) -> Result<HttpResponse> {
let user = User::find_by_id(&pool, &claims.sub).await?;
Ok(HttpResponse::Ok().json(ApiResponse::success(UserInfo {
id: user.id,
username: user.username,
email: user.email,
full_name: user.full_name,
role: user.role,
})))
}