From d50de4e4d8a97132e370c05270fb4775aca0c4cb Mon Sep 17 00:00:00 2001 From: Zack <33050391+speed2exe@users.noreply.github.com> Date: Fri, 11 Aug 2023 08:43:21 +0800 Subject: [PATCH] feat: added capability to decode supabase web token (#8) --- Cargo.lock | 27 +++++++++++++ Cargo.toml | 1 + src/component/auth/mod.rs | 1 + src/component/auth/supabase_jwt.rs | 61 ++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+) create mode 100644 src/component/auth/supabase_jwt.rs diff --git a/Cargo.lock b/Cargo.lock index 5825e2d80515..303df866e51f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -458,6 +458,7 @@ dependencies = [ "derive_more", "fancy-regex", "futures-util", + "jsonwebtoken", "lazy_static", "once_cell", "openssl", @@ -1750,6 +1751,20 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "jsonwebtoken" +version = "8.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" +dependencies = [ + "base64 0.21.2", + "pem", + "ring", + "serde", + "serde_json", + "simple_asn1", +] + [[package]] name = "jwt" version = "0.16.0" @@ -2802,6 +2817,18 @@ dependencies = [ "libc", ] +[[package]] +name = "simple_asn1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror", + "time", +] + [[package]] name = "slab" version = "0.4.8" diff --git a/Cargo.toml b/Cargo.toml index 212e9a0ad853..ddf4efec29ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,6 +49,7 @@ bytes = "1.4.0" bincode = "1.3.3" dashmap = "5.4" rcgen = { version = "0.10.0", features = ["pem", "x509-parser"] } +jsonwebtoken = "8.3.0" # tracing tracing = { version = "0.1.37" } diff --git a/src/component/auth/mod.rs b/src/component/auth/mod.rs index 91ed9ea13912..61a06f85033e 100644 --- a/src/component/auth/mod.rs +++ b/src/component/auth/mod.rs @@ -1,5 +1,6 @@ mod error; mod password; +mod supabase_jwt; mod user; pub use error::*; diff --git a/src/component/auth/supabase_jwt.rs b/src/component/auth/supabase_jwt.rs new file mode 100644 index 000000000000..9a579ca3657a --- /dev/null +++ b/src/component/auth/supabase_jwt.rs @@ -0,0 +1,61 @@ +use anyhow::Error; +use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation}; +use serde::{Deserialize, Serialize}; + +lazy_static::lazy_static! { + pub static ref VALIDATION: Validation = Validation::new(Algorithm::HS256); +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(untagged)] +pub enum Token { + Anonymous(Anonymous), + Authenticated(Box), +} + +impl Token { + #[allow(dead_code)] + pub fn decode_from_str(&self, token: &str, secret: &[u8]) -> Result { + let token_data = decode::(token, &DecodingKey::from_secret(secret), &VALIDATION)?; + Ok(token_data.claims) + } +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Authenticated { + aud: String, + exp: u64, + iat: u64, + iss: String, + sub: String, + email: String, + phone: String, + app_metadata: AppMetadata, + user_metadata: std::collections::HashMap, // or another struct if you know the fields + role: String, + aal: String, + amr: Vec, + session_id: String, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Anonymous { + iss: String, + #[serde(rename = "ref")] + reference: String, + role: String, + iat: u64, + exp: u64, +} + +#[derive(Debug, Serialize, Deserialize)] +struct AppMetadata { + provider: String, + providers: Vec, +} + +#[derive(Debug, Serialize, Deserialize)] +struct Amr { + method: String, + timestamp: u64, +}