tower_oauth2_resource_server/
jwt_unverified.rs1use base64::prelude::BASE64_STANDARD_NO_PAD;
2
3#[derive(Debug, Clone)]
4pub struct UnverifiedJwt {
5 token: String,
6}
7
8impl UnverifiedJwt {
9 pub fn new(raw_token: impl Into<String>) -> Self {
10 UnverifiedJwt {
11 token: raw_token.into(),
12 }
13 }
14
15 pub fn as_str(&self) -> &str {
16 &self.token
17 }
18
19 pub fn header(&self) -> Option<serde_json::Value> {
20 let header_b64 = self.token.split('.').nth(0)?;
21 let header_bytes = base64::Engine::decode(&BASE64_STANDARD_NO_PAD, header_b64).ok()?;
22 let header_str = String::from_utf8(header_bytes).ok()?;
23 serde_json::from_str(&header_str).ok()?
24 }
25
26 pub fn claims(&self) -> Option<serde_json::Value> {
27 let claims_b64 = self.token.split('.').nth(1)?;
28 let claims_bytes = base64::Engine::decode(&BASE64_STANDARD_NO_PAD, claims_b64).unwrap();
29 let claims_str = String::from_utf8(claims_bytes).ok()?;
30 serde_json::from_str(&claims_str).ok()?
31 }
32}
33
34#[cfg(test)]
35mod tests {
36 use serde_json::json;
37
38 use super::*;
39
40 const VALID_TOKEN: &str = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.KMUFsIDTnFmyG3nMiGM6H9FNFUROf3wh7SmqJp-QV30";
41
42 #[test]
43 fn parse_header() {
44 let header = UnverifiedJwt::new(VALID_TOKEN).header();
45 assert!(header.is_some());
46 assert_eq!(
47 header,
48 Some(json!({
49 "alg": "HS256",
50 "typ": "JWT"
51 }))
52 );
53 }
54
55 #[test]
56 fn parse_claims() {
57 let claims = UnverifiedJwt::new(VALID_TOKEN).claims();
58 assert!(claims.is_some());
59 assert_eq!(
60 claims,
61 Some(json!({
62 "sub": "1234567890",
63 "name": "John Doe",
64 "admin": true,
65 "iat": 1516239022
66 }))
67 );
68 }
69}