# pasta_tokens PASETO implementation for Rust. ## Examples ```rust use pasta_tokens::{v4, paserk::k4, purpose::public::Public, Json}; #[derive(serde::Serialize, serde::Deserialize)] struct Footer { /// The ID of the key used to sign the PASETO. /// A footer should only contain types that are `SafeForFooter` kid: k4::KeyId, } #[derive(serde::Serialize, serde::Deserialize)] struct Payload { /// The expiration date of the token #[serde(with = "time::serde::rfc3339", rename = "exp")] expiration: time::OffsetDateTime, /// The subject of the token #[serde(rename = "sub")] user_id: uuid::Uuid, } // load your secret key let secret_key = hex::decode("407796f4bc4b8184e9fe0c54b336822d34823092ad873d87ba14c3efb9db8c1d").unwrap(); let secret_key = v4::SecretKey::from_secret_key(secret_key.try_into().unwrap()); let user_id = uuid::Uuid::new_v4(); // create the token payload and footer. let token = v4::UnsignedToken::new_v4_public(Payload { // expires in 1 hour expiration: time::OffsetDateTime::now_utc() + time::Duration::hours(1), user_id, }) .with_footer(Json(Footer { kid: secret_key.public_key().to_id(), })) // sign with the secret key .sign(&secret_key) .unwrap() .to_string(); // Send off the token to the client println!("{token}"); // "v4.public.eyJleHAiOiIyMDIzLTEwLTAxVDE0OjQ4OjI2LjM0NjA5MloiLCJzdWIiOiIxOTBhZjFmYS1lZGVlLTRiNGUtOGQxMC05ZmUwZjQ1ZGQ5OTQifXo-Vsr45NroJZ9pLkuN3xcxgFncGF3eject5GdZH7WwTEfCgmo6hD-zNh0txsLvZi1vC601oNCgXq_2cK4XKQw.eyJraWQiOiJrNC5waWQuQUdQQ09CUkI4UHowQ3dNOFFfQnNVUEw0OF8zZjRUbE0yc2Z0R3Y0ejkzVFkifQ" // load your public keys let public_key = hex::decode("b7715bd661458d928654d3e832f53ff5c9480542e0e3d4c9b032c768c7ce6023").unwrap(); let public_key = v4::PublicKey::from_public_key(&public_key).unwrap(); // keep a key cache of key IDs to public keys. // this will let you securely rotate your secret keys // and still validate multiple public keys safely let keys = std::collections::HashMap::from([ (public_key.to_id(), public_key) ]); // Parse the token from the client let token: v4::SignedToken> = token.parse().expect("should be a valid token format"); // using the key ID, search for the public key let key = &keys[&token.unverified_footer().0.kid]; // verify the token signature let token: v4::VerifiedToken = token.verify(key).expect("token should be signed by us"); // check if the token has expired assert!(token.message.expiration > time::OffsetDateTime::now_utc()); // proceed to use the payload as you wish! assert_eq!(token.message.user_id, user_id); ```