https://github.com/conradludgate/pasta-tokens
A correct, fast and ergonomic PASETO library for Rust
https://github.com/conradludgate/pasta-tokens
authentication paserk paseto rust tokens
Last synced: 3 months ago
JSON representation
A correct, fast and ergonomic PASETO library for Rust
- Host: GitHub
- URL: https://github.com/conradludgate/pasta-tokens
- Owner: conradludgate
- License: mit
- Created: 2023-08-02T21:53:26.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2023-10-03T14:23:10.000Z (over 2 years ago)
- Last Synced: 2026-02-08T10:47:28.587Z (4 months ago)
- Topics: authentication, paserk, paseto, rust, tokens
- Language: Rust
- Homepage:
- Size: 509 KB
- Stars: 8
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
- Security: SECURITY.md
Awesome Lists containing this project
README
# 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);
```