feat(auth): 实现登录限流和性能优化
性能优化: - 添加数据库索引优化查询性能 (006) - weather_data: user_id, date, is_favorite 索引 - users: openid 索引 - payment_orders: status 索引 - 新增 refresh_tokens 表支持双 Token 机制 (004) - 新增 web_login_codes 表支持网页端扫码登录 (005) 安全增强: - 实现基于 IP 的登录限流 (rate_limiter.rs) - 滑动窗口算法: 5次/分钟/IP - 自动清理过期记录 - 429 TooManyRequests 响应 新模块: - src/rate_limiter.rs: 限流模块 - src/alipay.rs: 支付宝签名模块 (RSA2) - src/error.rs: 统一错误类型 (含 TooManyRequests) - src/handlers/meta.rs: 元数据处理器 代码清理: - 修复 .gitignore 规则,正确跟踪 src/ 和 migrations/
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use actix_web::{web, HttpResponse, Responder, post, get};
|
||||
use actix_web::{web, HttpResponse, HttpRequest, Responder, post, get};
|
||||
use chrono::{Utc, Duration};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use reqwest::Client;
|
||||
@@ -13,6 +13,8 @@ use crate::models::{
|
||||
AppState, LoginResponse, RefreshTokenRequest, TokenRefreshResponse,
|
||||
WeChatApiResponse, WeChatLoginRequest,
|
||||
};
|
||||
use crate::rate_limiter::LOGIN_RATE_LIMITER;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[post("/api/login")]
|
||||
pub async fn login(
|
||||
@@ -20,7 +22,27 @@ pub async fn login(
|
||||
req: web::Json<WeChatLoginRequest>,
|
||||
http_client: web::Data<Client>,
|
||||
app_state: web::Data<AppState>,
|
||||
http_req: HttpRequest,
|
||||
) -> impl Responder {
|
||||
let client_ip = http_req
|
||||
.headers()
|
||||
.get("X-Forwarded-For")
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.map(|s| s.split(',').next().unwrap_or(s).trim().to_string())
|
||||
.or_else(|| {
|
||||
http_req
|
||||
.headers()
|
||||
.get("X-Real-IP")
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.map(|s| s.to_string())
|
||||
})
|
||||
.unwrap_or_else(|| "unknown".to_string());
|
||||
|
||||
if let Err(e) = LOGIN_RATE_LIMITER.check_rate_limit(&client_ip).await {
|
||||
warn!("登录请求被限流: client_ip={}", client_ip);
|
||||
return HttpResponse::TooManyRequests().json(ErrorResponse::<()>::error(e.to_string()));
|
||||
}
|
||||
|
||||
let url = format!(
|
||||
"https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code",
|
||||
app_state.wechat_appid, app_state.wechat_secret, req.code
|
||||
|
||||
Reference in New Issue
Block a user