4 releases (2 breaking)
Uses old Rust 2015
0.3.1 | Mar 21, 2017 |
---|---|
0.3.0 | Mar 19, 2017 |
0.2.0 | Mar 16, 2017 |
0.1.0 | Mar 10, 2017 |
#2 in #twist
Used in 2 crates
49KB
975 lines
twist-jwt
An implementation of RFC7519 JSON Web Token (JWT).
lib.rs
:
JSON Web Token (JWT) implementation for twist.
Examples
Encode/Decode the sample token from jwt.io
#
#
#[derive(Clone, Deserialize, PartialEq, Serialize)]
pub struct Claims {
pub sub: String,
pub name: String,
pub admin: bool,
}
// Our super 'secret'
let secret = "secret".as_bytes();
// Sample Token from jwt.io.
let actual = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.\
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.\
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ";
// Default JOSE Header (alg: HS256, typ: 'JWT').
let mut header: Header = Default::default();
// The jwt.io sample claims. This can really be anything as long as its
// 'Clone + Deserialize + Serialize'.
let claims = Claims {
sub: "1234567890".to_string(),
name: "John Doe".to_string(),
admin: true,
};
// Encode the header and claims with the given secret, and ensure it's the same as the sample
// token.
let mut token = String::new();
match encode::jwt(&header, &claims, &secret) {
Ok(tok) => {
assert!(tok == actual);
token = tok;
},
Err(_) => assert!(false),
}
// Now decode the token from above into it's parts.
match decode::jwt::<Claims>(&token, &secret, Algorithm::HS256) {
Ok(token_data) => {
assert!(token_data.header() == header);
assert!(token_data.claims() == claims);
}
Err(_) => assert!(false),
}
Encode/Decode/Verify with a set of registered claims.
#
#
#[derive(Clone, Deserialize, PartialEq, Serialize)]
pub struct Claims {
pub iss: String,
pub sub: String,
pub aud: String,
pub exp: DateTime<UTC>,
pub nbf: DateTime<UTC>,
pub iat: DateTime<UTC>,
pub jti: String,
}
impl Default for Claims {
fn default() -> Claims {
Claims {
iss: String::new(),
sub: String::new(),
aud: String::new(),
exp: UTC::now(),
nbf: UTC::now(),
iat: UTC::now(),
jti: String::new(),
}
}
}
impl verify::HasRegistered for Claims {
fn iss(&self) -> Option<String> {
Some(self.iss.clone())
}
fn sub(&self) -> Option<String> {
Some(self.sub.clone())
}
fn aud(&self) -> Option<String> {
Some(self.aud.clone())
}
fn exp(&self) -> Option<DateTime<UTC>> {
Some(self.exp.clone())
}
fn nbf(&self) -> Option<DateTime<UTC>> {
Some(self.nbf.clone())
}
fn iat(&self) -> Option<DateTime<UTC>> {
Some(self.iat.clone())
}
fn jti(&self) -> Option<String> {
Some(self.jti.clone())
}
}
// Our super 'secret'
let secret = "secret".as_bytes();
// Default JOSE Header (alg: HS256, typ: 'JWT').
let header: Header = Default::default();
// Our time based claims.
let now: DateTime<UTC> = UTC::now();
let exp = now.checked_add_signed(Duration::minutes(10)).expect("invalid exp");
let nbf = now.checked_sub_signed(Duration::seconds(10)).expect("invalid nbf");
// The jwt.io sample claims. This can really be anything as long as its
// 'Clone + Deserialize + Serialize'.
let claims = Claims {
iss: "me".to_string(),
sub: "me".to_string(),
aud: "you".to_string(),
exp: exp,
nbf: nbf,
iat: now,
jti: "my unique id".to_string(),
};
// Encode the header and claims with the given secret.
let mut token = String::new();
match encode::jwt(&header, &claims, &secret) {
Ok(tok) => token = tok,
Err(_) => assert!(false),
}
// Now decode the token from above into it's parts.
let mut unverified: Claims = Default::default();
match decode::jwt::<Claims>(&token, &secret, Algorithm::HS256) {
Ok(token_data) => {
assert!(token_data.header() == header);
assert!(token_data.claims() == claims);
unverified = token_data.claims();
}
Err(_) => assert!(false),
}
// Verify the claims
assert!(verify::claims(&unverified, &claims, verify::ALL));
// Adjust the unverified.
unverified.iss = "notme".to_string();
// Verify should fail.
assert!(!verify::claims(&unverified, &claims, verify::ALL));
Dependencies
~20–29MB
~531K SLoC