<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          用 Rust 構(gòu)建 API 系列教程:第三部分

          共 5440字,需瀏覽 11分鐘

           ·

          2021-09-21 14:46

          今天繼續(xù)使用 Rust 構(gòu)建 API,第三部分,也是最后一部分。

          這部分,我將解釋如何使用 JWT (JSON Web Token)保護(hù) POST /items 端點(diǎn)。

          同樣,我把所有代碼放在同一個(gè)文件(src/main.rs)中,實(shí)際項(xiàng)目你不應(yīng)該這么做。

          如果沒有閱讀之前的部分,請(qǐng)先閱讀。

          準(zhǔn)備

          我們需要在 .env 文件中增加一個(gè)新的環(huán)境變量。打開 .env 文件,然后在 MONGODB_URI 下方添加一個(gè)名為 JWT_SECRET 的新變量,并將值設(shè)置為你喜歡的任何值。

          添加新的依賴項(xiàng)

          我們需要添加一個(gè)新的依賴:jsonwebtoken

          jsonwebtoken 是一個(gè)允許我們對(duì) JWTs 進(jìn)行編碼、解碼和驗(yàn)證的 crate。

          用新的依賴項(xiàng)更新 Cargo.toml 文件。

          [dependencies]
          tide = "0.16"
          async-std = { version = "1", features = ["attributes"] }
          serde = { version = "1", features = ["derive"] }
          dotenv = "0.15"
          mongodb = { version = "1", features = ["async-std-runtime"], default-features = false }
          jsonwebtoken = "7"

          開始編碼

          We need to make some modifications to the code. First update the imports with the following

          我們需要對(duì)代碼進(jìn)行一些修改。首先是導(dǎo)入部分:

          use async_std::stream::StreamExt;
          use dotenv::dotenv;
          use jsonwebtoken;
          use mongodb::bson::doc;
          use serde::{Deserialize, Serialize};
          use std::{env, future::Future, pin::Pin};
          use tide::{Body, Next, Request, Response, StatusCode};

          這些都是我們將使用到的模塊。

          我們需要?jiǎng)?chuàng)建一個(gè)新的結(jié)構(gòu)體來定義 JWT 的有效負(fù)載(payload)。我不會(huì)在有效負(fù)載中添加任何內(nèi)容,所以它只是一個(gè)空結(jié)構(gòu)體。

          src/main.rs 文件中添加以下內(nèi)容:

          #[derive(Serialize, Deserialize)]
          struct TokenClaims {}

          現(xiàn)在我們有了 TokenClaims,我們需要編寫中間件函數(shù)。加到 src/main.rs 中:

          fn auth_middleware<'a>(
            req: Request<State>,
            next: Next<'a, State>,
          ) -> Pin<Box<dyn Future<Output = tide::Result> + Send + 'a>> {
            return Box::pin(async {
              // Retrieve the "Authorization" header from the request
              let authorization_header = req.header("Authorization");

              // Check that the "Authorization" header is not missing
              // if it is missing, respond with 401
              let authorization_header = match authorization_header {
                Some(h) => h.as_str(),
                None => {
                  return Ok(Response::new(StatusCode::Unauthorized));
                }
              };

              // Attempt to remove the "Bearer " prefix
              // if it does not start with "Bearer " respond with 401
              let token = match authorization_header.strip_prefix("Bearer ") {
                Some(t) => t,
                None => {
                  return Ok(Response::new(StatusCode::Unauthorized));
                }
              };

              // Retrieve the "JWT_SECRET" environment variable
              let secret = env::var("JWT_SECRET").unwrap();

              // Decode the JWT
              let token = jsonwebtoken::decode::<TokenClaims>(
                token,
                &jsonwebtoken::DecodingKey::from_secret(secret.as_ref()),
                // Do not require the "exp" claim in the token payload
                &jsonwebtoken::Validation {
                  validate_exp: false,
                  ..Default::default()
                },
              );

              // If there was an error when decoding the token respond with 401
              if token.is_err() {
                return Ok(Response::new(StatusCode::Unauthorized));
              }

              // The request is authorized, proceed with the next controller
              return Ok(next.run(req).await);
            });
          }

          注意上面的注釋。

          總之,中間件檢查請(qǐng)求中是否有一個(gè) Authorization 頭。然后它嘗試從頭部獲取 JWT。最后,使用 jsonwebtoken crate,嘗試解碼 JWT。如果在處理過程中出現(xiàn)任何錯(cuò)誤,該函數(shù)將使用 401 HTTP 狀態(tài)碼對(duì)未經(jīng)授權(quán)進(jìn)行響應(yīng)。否則,請(qǐng)求被授權(quán),中間件運(yùn)行鏈中的下一個(gè)控制器。

          我們必須修改主函數(shù)來使用這個(gè)新的中間件,像這樣更新 POST /items 路由:

          app.at("/items").with(auth_middleware).post(post_item);

          啟動(dòng)服務(wù)器測(cè)試下:

          cargo run

          如果你想發(fā)送一個(gè) POST 請(qǐng)求到 /items ( http://localhost:8080/items ) ,你會(huì)得到一個(gè) 401 狀態(tài)碼。

          你需要使用在 .env 文件中設(shè)置的秘鑰生成一個(gè) JWT。一個(gè)簡(jiǎn)單的方法是轉(zhuǎn)到 jwt.io,將有效負(fù)載更改為空 JSON 對(duì)象 {} ,并用自己的方法替換默認(rèn)的 secret。然后你可以復(fù)制這個(gè) token。

          在發(fā)送請(qǐng)求之前,請(qǐng)確保添加一個(gè)  Authorization 頭,其值為 Bearer YOUR_JWT_TOKEN。當(dāng)然,用實(shí)際的令牌替換 YOUR_JWT_TOKEN

          現(xiàn)在,如果你嘗試再次發(fā)送 POST 請(qǐng)求,你應(yīng)該得到一個(gè) 200 狀態(tài)代碼!

          完結(jié)

          本系列教程就結(jié)束了。

          沒有涉及到很多復(fù)雜的內(nèi)容,但講解了 Web API 涉及到的一些基本知識(shí)。通過框架,Rust 開發(fā) API 也還是挺快的,你覺得呢?




          往期推薦


          我是 polarisxu,北大碩士畢業(yè),曾在 360 等知名互聯(lián)網(wǎng)公司工作,10多年技術(shù)研發(fā)與架構(gòu)經(jīng)驗(yàn)!2012 年接觸 Go 語言并創(chuàng)建了 Go 語言中文網(wǎng)!著有《Go語言編程之旅》、開源圖書《Go語言標(biāo)準(zhǔn)庫》等。


          堅(jiān)持輸出技術(shù)(包括 Go、Rust 等技術(shù))、職場(chǎng)心得和創(chuàng)業(yè)感悟!歡迎關(guān)注「polarisxu」一起成長(zhǎng)!也歡迎加我微信好友交流:gopherstudio

          瀏覽 131
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美变态性爱一区二区三区 | 欧美精品18videosex性欧美 | 黄色免费看 | 婷婷综合导航 | 色老板最新凹凸视频 |