4 个版本 (2 个重大更改)
使用旧的 Rust 2015
0.3.1 | 2017年3月21日 |
---|---|
0.3.0 | 2017年3月19日 |
0.2.0 | 2017年3月16日 |
0.1.0 | 2017年3月10日 |
#2 in #twist
被 2 个 crate 使用
49KB
975 行代码
twist-jwt
RFC7519 JSON Web Token (JWT) 的实现。
lib.rs
:
twist 的 JSON Web Token (JWT) 实现。
示例
编码/解码来自 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),
}
使用一组注册声明进行编码/解码/验证
#
#
#[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));
依赖项
~20–29MB
~531K SLoC