tide_jsonwebtoken/
lib.rs

1use jsonwebtoken::{decode, DecodingKey, EncodingKey, Header, Validation};
2use serde::{Deserialize, Serialize};
3use tide::{Middleware, Next, Request, Response, StatusCode};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct Claims {
7    pub sub: String,
8    pub username: String,
9    pub uid: String,
10    pub exp: u64,
11    pub login_time: u64,
12}
13
14#[derive(Clone)]
15pub struct ApiKeyMiddleware {
16    secret_key: String,
17}
18
19impl ApiKeyMiddleware {
20    pub fn new(secret_key: &str) -> Self {
21        Self {
22            secret_key: secret_key.to_string(),
23        }
24    }
25
26    pub fn gen_token(
27        &self,
28        sub: &str,
29        username: &str,
30        uid: &str,
31        exp: u64,
32        login_time: u64,
33    ) -> Result<String, jsonwebtoken::errors::Error> {
34        let claims = Claims {
35            sub: sub.to_string(),
36            username: username.to_string(),
37            uid: uid.to_string(),
38            exp,
39            login_time,
40        };
41        jsonwebtoken::encode(
42            &Header::default(),
43            &claims,
44            &EncodingKey::from_secret(&self.secret_key.as_bytes()),
45        )
46    }
47}
48
49#[async_trait::async_trait]
50impl<State: Clone + Send + Sync + 'static> Middleware<State> for ApiKeyMiddleware {
51    async fn handle(&self, mut req: Request<State>, next: Next<'_, State>) -> tide::Result {
52        if let Some(api_key) = req.header("x-api-key") {
53            let token_data = decode::<Claims>(
54                &api_key.as_str(),
55                &DecodingKey::from_secret(self.secret_key.as_bytes()),
56                &Validation::default(),
57            );
58
59            match token_data {
60                Ok(data) => {
61                    let claims = data.claims;
62                    // TODO: Check sub type
63                    req.set_ext(claims);
64                    Ok(next.run(req).await)
65                }
66                Err(_) => {
67                    let mut res = Response::new(StatusCode::Unauthorized);
68                    res.set_body("Invalid API key");
69                    Ok(res)
70                }
71            }
72        } else {
73            let mut res = Response::new(StatusCode::Unauthorized);
74            res.set_body("API key missing");
75            Ok(res)
76        }
77    }
78}