fix(auth): /weather/details 端点自己验证 JWT(修复静默刷新后仍 401 问题)
问题:/weather/details 不在 jwt_middleware 保护范围内,导致即使前端发送 Authorization header,后端也不会验证 JWT。 修复:使用 HttpRequest 直接从 Authorization header 提取并验证 JWT,而非依赖 middleware 注入的 Claims。 验证:curl 测试确认 /weather/details?id=2 返回正确数据
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
use actix_web::{web, delete, get, post, HttpResponse};
|
use actix_web::{web, delete, get, post, HttpRequest, HttpResponse};
|
||||||
use sqlx::postgres::PgPool;
|
use sqlx::postgres::PgPool;
|
||||||
use tracing::{debug, info};
|
use tracing::{debug, info};
|
||||||
|
|
||||||
@@ -60,19 +60,28 @@ pub async fn generate_temp_token_handler(
|
|||||||
#[get("/weather/details")]
|
#[get("/weather/details")]
|
||||||
pub async fn get_weather_details(
|
pub async fn get_weather_details(
|
||||||
pool: web::Data<PgPool>,
|
pool: web::Data<PgPool>,
|
||||||
claims: Option<web::ReqData<Claims>>,
|
req: HttpRequest,
|
||||||
query: web::Query<serde_json::Value>,
|
query: web::Query<serde_json::Value>,
|
||||||
app_state: web::Data<AppState>,
|
app_state: web::Data<AppState>,
|
||||||
) -> Result<HttpResponse, AppError> {
|
) -> Result<HttpResponse, AppError> {
|
||||||
let mut is_temp_token = false;
|
let mut is_temp_token = false;
|
||||||
|
|
||||||
|
// 从 Authorization header 中提取并验证 JWT(自己处理,不依赖 middleware)
|
||||||
|
let claims_from_header = || -> Option<Claims> {
|
||||||
|
let auth_header = req.headers().get("Authorization")?;
|
||||||
|
let auth_str = auth_header.to_str().ok()?;
|
||||||
|
let token = auth_str.strip_prefix("Bearer ")?;
|
||||||
|
let jwt_secret = &app_state.jwt_secret;
|
||||||
|
auth::verify_token(token, jwt_secret).ok()
|
||||||
|
};
|
||||||
|
|
||||||
let (openid, weather_id) =
|
let (openid, weather_id) =
|
||||||
if let Some(temp_token) = query.get("temp_token").and_then(|v| v.as_str()) {
|
if let Some(temp_token) = query.get("temp_token").and_then(|v| v.as_str()) {
|
||||||
is_temp_token = true;
|
is_temp_token = true;
|
||||||
let temp_claims = auth::verify_temp_token(temp_token, &app_state.jwt_secret)
|
let temp_claims = auth::verify_temp_token(temp_token, &app_state.jwt_secret)
|
||||||
.map_err(|e| AppError::Unauthorized(format!("临时token无效: {}", e)))?;
|
.map_err(|e| AppError::Unauthorized(format!("临时token无效: {}", e)))?;
|
||||||
(temp_claims.openid, temp_claims.resource_id)
|
(temp_claims.openid, temp_claims.resource_id)
|
||||||
} else if let Some(claims) = claims {
|
} else if let Some(claims) = claims_from_header() {
|
||||||
let weather_id = match query.get("id") {
|
let weather_id = match query.get("id") {
|
||||||
Some(v) if v.is_i64() => v.as_i64().unwrap() as i32,
|
Some(v) if v.is_i64() => v.as_i64().unwrap() as i32,
|
||||||
Some(v) if v.is_string() => {
|
Some(v) if v.is_string() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user