live_kit_server: Replace `jwt` with `jsonwebtoken` (#15302)

Marshall Bowers created

This PR replaces `live_kit_server`'s usage of `jwt` with `jsonwebtoken`.

`jwt` hasn't been updated in 2 years and seems unmaintained.

`jsonwebtoken` has significantly more downloads and appears to be a
healthier crate overall.

Release Notes:

- N/A

Change summary

Cargo.lock                          | 42 ++++++++++++++++++++++--------
Cargo.toml                          |  1 
crates/live_kit_server/Cargo.toml   |  4 --
crates/live_kit_server/src/token.rs | 23 ++++++++++------
4 files changed, 47 insertions(+), 23 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -5843,18 +5843,18 @@ dependencies = [
 ]
 
 [[package]]
-name = "jwt"
-version = "0.16.0"
+name = "jsonwebtoken"
+version = "9.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6204285f77fe7d9784db3fdc449ecce1a0114927a51d5a41c4c7a292011c015f"
+checksum = "b9ae10193d25051e74945f1ea2d0b42e03cc3b890f7e4cc5faa44997d808193f"
 dependencies = [
- "base64 0.13.1",
- "crypto-common",
- "digest",
- "hmac",
+ "base64 0.21.7",
+ "js-sys",
+ "pem",
+ "ring",
  "serde",
  "serde_json",
- "sha2",
+ "simple_asn1",
 ]
 
 [[package]]
@@ -6275,15 +6275,13 @@ version = "0.1.0"
 dependencies = [
  "anyhow",
  "async-trait",
- "hmac",
- "jwt",
+ "jsonwebtoken",
  "log",
  "prost",
  "prost-build",
  "prost-types",
  "reqwest",
  "serde",
- "sha2",
 ]
 
 [[package]]
@@ -7540,6 +7538,16 @@ version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
 
+[[package]]
+name = "pem"
+version = "3.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae"
+dependencies = [
+ "base64 0.22.0",
+ "serde",
+]
+
 [[package]]
 name = "pem-rfc7468"
 version = "0.7.0"
@@ -9777,6 +9785,18 @@ version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1ad1d488a557b235fc46dae55512ffbfc429d2482b08b4d9435ab07384ca8aec"
 
+[[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 = "simplecss"
 version = "0.2.1"

Cargo.toml 🔗

@@ -354,6 +354,7 @@ isahc = { version = "1.7.2", default-features = false, features = [
     "text-decoding",
 ] }
 itertools = "0.11.0"
+jsonwebtoken = "9.3"
 lazy_static = "1.4.0"
 libc = "0.2"
 linkify = "0.10.0"

crates/live_kit_server/Cargo.toml 🔗

@@ -16,14 +16,12 @@ doctest = false
 [dependencies]
 anyhow.workspace = true
 async-trait.workspace = true
-hmac = "0.12"
-jwt = "0.16"
+jsonwebtoken.workspace = true
 log.workspace = true
 prost.workspace = true
 prost-types.workspace = true
 reqwest = "0.11"
 serde.workspace = true
-sha2.workspace = true
 
 [build-dependencies]
 prost-build.workspace = true

crates/live_kit_server/src/token.rs 🔗

@@ -1,15 +1,13 @@
 use anyhow::{anyhow, Result};
-use hmac::{Hmac, Mac};
-use jwt::{SignWithKey, VerifyWithKey};
+use jsonwebtoken::{DecodingKey, EncodingKey, Header, Validation};
 use serde::{Deserialize, Serialize};
-use sha2::Sha256;
 use std::{
     borrow::Cow,
     ops::Add,
     time::{Duration, SystemTime, UNIX_EPOCH},
 };
 
-static DEFAULT_TTL: Duration = Duration::from_secs(6 * 60 * 60); // 6 hours
+const DEFAULT_TTL: Duration = Duration::from_secs(6 * 60 * 60); // 6 hours
 
 #[derive(Default, Serialize, Deserialize)]
 #[serde(rename_all = "camelCase")]
@@ -81,8 +79,6 @@ pub fn create(
         ))?;
     }
 
-    let secret_key: Hmac<Sha256> = Hmac::new_from_slice(secret_key.as_bytes())?;
-
     let now = SystemTime::now();
 
     let claims = ClaimGrants {
@@ -98,10 +94,19 @@ pub fn create(
         jwtid: identity.map(Cow::Borrowed),
         video: video_grant,
     };
-    Ok(claims.sign_with_key(&secret_key)?)
+    Ok(jsonwebtoken::encode(
+        &Header::default(),
+        &claims,
+        &EncodingKey::from_secret(secret_key.as_ref()),
+    )?)
 }
 
 pub fn validate<'a>(token: &'a str, secret_key: &str) -> Result<ClaimGrants<'a>> {
-    let secret_key: Hmac<Sha256> = Hmac::new_from_slice(secret_key.as_bytes())?;
-    Ok(token.verify_with_key(&secret_key)?)
+    let token = jsonwebtoken::decode(
+        token,
+        &DecodingKey::from_secret(secret_key.as_ref()),
+        &Validation::default(),
+    )?;
+
+    Ok(token.claims)
 }