summaryrefslogtreecommitdiffstats
path: root/src/jwt.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/jwt.rs')
-rw-r--r--src/jwt.rs51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/jwt.rs b/src/jwt.rs
new file mode 100644
index 0000000..6382a01
--- /dev/null
+++ b/src/jwt.rs
@@ -0,0 +1,51 @@
+use std::sync::Arc;
+
+use axum::extract::{Request, State};
+use axum_extra::{
+ headers::{authorization::Bearer, Authorization},
+ TypedHeader,
+};
+use jsonwebtoken::{DecodingKey, Validation};
+use serde::{Deserialize, Serialize};
+use uuid::Uuid;
+
+use crate::{error::AuthError, state::AppState};
+
+#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
+pub struct Claims {
+ pub sub: Uuid,
+ pub iat: i64,
+ pub exp: i64,
+}
+
+impl Claims {
+ pub fn new(sub: Uuid, max_age: time::Duration) -> Self {
+ let iat = time::OffsetDateTime::now_utc().unix_timestamp();
+ let exp = iat + max_age.whole_seconds();
+ Self { sub, iat, exp }
+ }
+
+ pub fn encode(&self, secret: &[u8]) -> Result<String, jsonwebtoken::errors::Error> {
+ jsonwebtoken::encode(
+ &jsonwebtoken::Header::default(),
+ self,
+ &jsonwebtoken::EncodingKey::from_secret(secret),
+ )
+ }
+}
+
+pub async fn authenticate(
+ State(state): State<Arc<AppState>>,
+ TypedHeader(Authorization(bearer)): TypedHeader<Authorization<Bearer>>,
+ mut req: Request,
+) -> Result<Request, AuthError> {
+ let claims = jsonwebtoken::decode::<Claims>(
+ bearer.token(),
+ &DecodingKey::from_secret(state.jwt_secret.as_ref()),
+ &Validation::default(),
+ )?
+ .claims;
+
+ req.extensions_mut().insert(claims);
+ Ok(req)
+}