python基礎02 條件控制 python條件語句是通過一條或多條語句的執行結果(Ture或者False)來執行的代碼塊 python中用elif代替了else if,所以if語句的關鍵字為:if-elif-else。 註意 每個條件後面都要用冒號:,表示接下來是滿足條件後要執行的語句塊 使用縮進 ...
剛開始學習rust的時候,web框架一大堆,感覺無所適從。有的框架類似於 springboot里註解的方式 使用巨集,有的是用函數的方式。
隨著非同步框架 tokio地位的穩固,axum是一個不錯的選擇。axum採用的是函數的方式。
其實框架里是寫好的驗證處理程式的。源碼里有基本驗證和令牌驗證兩種方式。
原來有的令牌驗證,一是欄位不能重新定義,二是欄位的值分為兩部分。如果前端的人不是深究過http協議,估計會罵街。
前端提交了用戶名和密碼後,得到了 jwt。後續業務中,將jwt放置到 商量好 的自定義header里即可。
以令牌里只涉及 用戶ID 和 過期時間 為例 定義 Claims。
#[derive(Debug, Serialize, Deserialize)] pub struct Claims { uid: String, exp: u64, // Unix stamp at expired time } impl std::fmt::Display for Claims { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self) } }
提取 jwt 獲得 claims, 自定義的header為 "x-token"
// 處理從 header獲取自定義欄位的 jwt,並驗證。 #[async_trait] impl<B> axum::extract::FromRequest<B> for Claims where B: Send { type Rejection = AuthError; async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> { let token = req.headers() .get("x-token") .map(|x| x.to_str().unwrap_or("")) .unwrap_or(""); tracing::info!(token); if token.is_empty() { return Err(AuthError::TokenNone); } let token_data = jsonwebtoken::decode::<Claims>(token, &DecodingKey::from_secret(&crate::config::ARGS.get().unwrap().secret.as_bytes()), &Validation::default()) .map_err(|_| AuthError::TokenInvalid)?; // Ok(token_data.claims) } }
處理程式。payload是具體業務數據。需要驗證提交的jwt時,參數裡加入 claims,就這麼簡單。
// handler pub async fn auth_jwt(axum::Json(payload): axum::Json<AuthUser>, claims: Claims) -> Result<String, AuthError> { tracing::info!("claim is {:?}", claims); Ok(format!("jwt ok, uid is {},user data {} {}", claims.uid, payload.username, payload.password)) }