No need to pass an algorithm to decode
This commit is contained in:
parent
d8439b1053
commit
fc9f83b837
|
@ -35,7 +35,7 @@ Look at custom headers section to see how to change that.
|
||||||
|
|
||||||
### Decoding
|
### Decoding
|
||||||
```rust
|
```rust
|
||||||
let token = decode::<Claims>(&token, "secret", Algorithm::HS256, &Validation::default()).unwrap();
|
let token = decode::<Claims>(&token, "secret", &Validation::default()).unwrap();
|
||||||
// token is a struct with 2 params: header and claims
|
// token is a struct with 2 params: header and claims
|
||||||
```
|
```
|
||||||
`decode` can error for a variety of reasons:
|
`decode` can error for a variety of reasons:
|
||||||
|
@ -47,10 +47,11 @@ let token = decode::<Claims>(&token, "secret", Algorithm::HS256, &Validation::de
|
||||||
### Validation
|
### Validation
|
||||||
This library validates automatically the `iat`, `exp` and `nbf` claims if found. You can also validate the `sub`, `iss` and `aud` but
|
This library validates automatically the `iat`, `exp` and `nbf` claims if found. You can also validate the `sub`, `iss` and `aud` but
|
||||||
those require setting the expected value.
|
those require setting the expected value.
|
||||||
You can add some leeway to the `iat`, `exp` and `nbf` validation by setting the `leeway` parameter as shown in the example below.
|
You can add some leeway to the `iat`, `exp` and `nbf` validation by setting the `leeway` parameter as shown in the example below as well
|
||||||
|
as select allowed algorithms.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use jsonwebtoken::Validation;
|
use jsonwebtoken::{Validation, Algorithm};
|
||||||
|
|
||||||
// Default valuation
|
// Default valuation
|
||||||
let validation = Validation::default();
|
let validation = Validation::default();
|
||||||
|
@ -62,6 +63,8 @@ let mut validation = Validation {iss: Some("issuer".to_string()), ..Default::def
|
||||||
let mut validation = Validation::default();
|
let mut validation = Validation::default();
|
||||||
validation.set_audience(&"Me"); // string
|
validation.set_audience(&"Me"); // string
|
||||||
validation.set_audience(&["Me", "You"]); // array of strings
|
validation.set_audience(&["Me", "You"]); // array of strings
|
||||||
|
// Will error if the token given has an algorithm that isn't HS256
|
||||||
|
let mut validation = Validation {algorithms: Some(vec![Algorithm::HS256]), ..Default::default()};
|
||||||
```
|
```
|
||||||
|
|
||||||
It's also possible to disable verifying the signature of a token by setting the `validate_signature` to `false`. This should
|
It's also possible to disable verifying the signature of a token by setting the `validate_signature` to `false`. This should
|
||||||
|
|
|
@ -25,5 +25,5 @@ fn bench_encode(b: &mut test::Bencher) {
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_decode(b: &mut test::Bencher) {
|
fn bench_decode(b: &mut test::Bencher) {
|
||||||
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ";
|
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ";
|
||||||
b.iter(|| decode::<Claims>(token, "secret".as_ref(), Algorithm::HS256, &Validation::default()));
|
b.iter(|| decode::<Claims>(token, "secret".as_ref(), &Validation::default()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ fn main() {
|
||||||
};
|
};
|
||||||
println!("{:?}", token);
|
println!("{:?}", token);
|
||||||
|
|
||||||
let token_data = match decode::<Claims>(&token, key.as_ref(), Algorithm::HS512, &Validation::default()) {
|
let token_data = match decode::<Claims>(&token, key.as_ref(), &Validation::default()) {
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
Err(err) => match *err.kind() {
|
Err(err) => match *err.kind() {
|
||||||
ErrorKind::InvalidToken => panic!(), // Example on how to handle a specific error
|
ErrorKind::InvalidToken => panic!(), // Example on how to handle a specific error
|
||||||
|
|
|
@ -2,7 +2,7 @@ extern crate jsonwebtoken as jwt;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
use jwt::{encode, decode, Header, Algorithm, Validation};
|
use jwt::{encode, decode, Header, Validation};
|
||||||
use jwt::errors::{ErrorKind};
|
use jwt::errors::{ErrorKind};
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,10 +23,9 @@ fn main() {
|
||||||
Err(_) => panic!() // in practice you would return the error
|
Err(_) => panic!() // in practice you would return the error
|
||||||
};
|
};
|
||||||
|
|
||||||
println!("{:?}", token);
|
|
||||||
let validation = Validation {sub: Some("b@b.com".to_string()), ..Validation::default()};
|
let validation = Validation {sub: Some("b@b.com".to_string()), ..Validation::default()};
|
||||||
|
|
||||||
let token_data = match decode::<Claims>(&token, key.as_ref(), Algorithm::HS256, &validation) {
|
let token_data = match decode::<Claims>(&token, key.as_ref(), &validation) {
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
Err(err) => match *err.kind() {
|
Err(err) => match *err.kind() {
|
||||||
ErrorKind::InvalidToken => panic!(), // Example on how to handle a specific error
|
ErrorKind::InvalidToken => panic!(), // Example on how to handle a specific error
|
||||||
|
|
|
@ -4,7 +4,7 @@ use ring;
|
||||||
|
|
||||||
error_chain! {
|
error_chain! {
|
||||||
errors {
|
errors {
|
||||||
/// When a token doesn't have a valid token shape
|
/// When a token doesn't have a valid JWT shape
|
||||||
InvalidToken {
|
InvalidToken {
|
||||||
description("invalid token")
|
description("invalid token")
|
||||||
display("Invalid token")
|
display("Invalid token")
|
||||||
|
@ -14,11 +14,6 @@ error_chain! {
|
||||||
description("invalid signature")
|
description("invalid signature")
|
||||||
display("Invalid signature")
|
display("Invalid signature")
|
||||||
}
|
}
|
||||||
/// When the algorithm in the header doesn't match the one passed to `decode`
|
|
||||||
WrongAlgorithmHeader {
|
|
||||||
description("wrong algorithm header")
|
|
||||||
display("Wrong Algorithm Header")
|
|
||||||
}
|
|
||||||
/// When the secret given is not a valid RSA key
|
/// When the secret given is not a valid RSA key
|
||||||
InvalidKey {
|
InvalidKey {
|
||||||
description("invalid key")
|
description("invalid key")
|
||||||
|
@ -57,6 +52,11 @@ error_chain! {
|
||||||
description("immature signature")
|
description("immature signature")
|
||||||
display("Immature Signature")
|
display("Immature Signature")
|
||||||
}
|
}
|
||||||
|
/// When the algorithm in the header doesn't match the one passed to `decode`
|
||||||
|
InvalidAlgorithm {
|
||||||
|
description("Invalid algorithm")
|
||||||
|
display("Invalid Algorithm")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreign_links {
|
foreign_links {
|
||||||
|
|
27
src/lib.rs
27
src/lib.rs
|
@ -89,7 +89,7 @@ macro_rules! expect_two {
|
||||||
/// ```rust,ignore
|
/// ```rust,ignore
|
||||||
/// #[macro_use]
|
/// #[macro_use]
|
||||||
/// extern crate serde_derive;
|
/// extern crate serde_derive;
|
||||||
/// use jsonwebtoken::{decode, Algorithm, Validation};
|
/// use jsonwebtoken::{decode, Validation};
|
||||||
///
|
///
|
||||||
/// #[derive(Debug, Serialize, Deserialize)]
|
/// #[derive(Debug, Serialize, Deserialize)]
|
||||||
/// struct Claims {
|
/// struct Claims {
|
||||||
|
@ -99,31 +99,26 @@ macro_rules! expect_two {
|
||||||
///
|
///
|
||||||
/// let token = "a.jwt.token".to_string();
|
/// let token = "a.jwt.token".to_string();
|
||||||
/// // Claims is a struct that implements Deserialize
|
/// // Claims is a struct that implements Deserialize
|
||||||
/// let token_data = decode::<Claims>(&token, "secret", Algorithm::HS256, &Validation::default());
|
/// let token_data = decode::<Claims>(&token, "secret", &Validation::default());
|
||||||
/// ```
|
/// ```
|
||||||
pub fn decode<T: DeserializeOwned>(token: &str, key: &[u8], algorithm: Algorithm, validation: &Validation) -> Result<TokenData<T>> {
|
pub fn decode<T: DeserializeOwned>(token: &str, key: &[u8], validation: &Validation) -> Result<TokenData<T>> {
|
||||||
let (signature, signing_input) = expect_two!(token.rsplitn(2, '.'));
|
let (signature, signing_input) = expect_two!(token.rsplitn(2, '.'));
|
||||||
|
let (claims, header) = expect_two!(signing_input.rsplitn(2, '.'));
|
||||||
|
let header: Header = from_jwt_part(header)?;
|
||||||
|
|
||||||
if validation.validate_signature && !verify(signature, signing_input, key, algorithm)? {
|
if validation.validate_signature && !verify(signature, signing_input, key, header.alg)? {
|
||||||
return Err(ErrorKind::InvalidSignature.into());
|
return Err(ErrorKind::InvalidSignature.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let (claims, header) = expect_two!(signing_input.rsplitn(2, '.'));
|
if let Some(ref allowed_algs) = validation.algorithms {
|
||||||
|
if !allowed_algs.contains(&header.alg) {
|
||||||
let header: Header = from_jwt_part(header)?;
|
return Err(ErrorKind::InvalidAlgorithm.into());
|
||||||
if header.alg != algorithm {
|
}
|
||||||
return Err(ErrorKind::WrongAlgorithmHeader.into());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let (decoded_claims, claims_map): (T, _) = from_jwt_part_claims(claims)?;
|
let (decoded_claims, claims_map): (T, _) = from_jwt_part_claims(claims)?;
|
||||||
|
|
||||||
validate(&claims_map, validation)?;
|
validate(&claims_map, validation)?;
|
||||||
|
|
||||||
Ok(TokenData { header: header, claims: decoded_claims })
|
Ok(TokenData { header: header, claims: decoded_claims })
|
||||||
}
|
}
|
||||||
|
|
||||||
// To consider:
|
|
||||||
//pub mod prelude {
|
|
||||||
// pub use crypto::{Algorithm, encode, decode};
|
|
||||||
// pub use validation::Validation;
|
|
||||||
// pub use header::Header;
|
|
||||||
//}
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ use serde_json::{Value, from_value, to_value};
|
||||||
use serde_json::map::Map;
|
use serde_json::map::Map;
|
||||||
|
|
||||||
use errors::{Result, ErrorKind};
|
use errors::{Result, ErrorKind};
|
||||||
|
use crypto::Algorithm;
|
||||||
|
|
||||||
|
|
||||||
/// Contains the various validations that are applied after decoding a token.
|
/// Contains the various validations that are applied after decoding a token.
|
||||||
|
@ -57,18 +58,23 @@ pub struct Validation {
|
||||||
/// Since `aud` can be either a String or a Vec<String> in the JWT spec, you will need to use
|
/// Since `aud` can be either a String or a Vec<String> in the JWT spec, you will need to use
|
||||||
/// the [set_audience](struct.Validation.html#method.set_audience) method to set it.
|
/// the [set_audience](struct.Validation.html#method.set_audience) method to set it.
|
||||||
///
|
///
|
||||||
/// Default to `None`.
|
/// Defaults to `None`.
|
||||||
pub aud: Option<Value>,
|
pub aud: Option<Value>,
|
||||||
/// If it contains a value, the validation will check that the `iss` field is the same as the
|
/// If it contains a value, the validation will check that the `iss` field is the same as the
|
||||||
/// one provided and will error otherwise.
|
/// one provided and will error otherwise.
|
||||||
///
|
///
|
||||||
/// Default to None
|
/// Defaults to `None`.
|
||||||
pub iss: Option<String>,
|
pub iss: Option<String>,
|
||||||
/// If it contains a value, the validation will check that the `sub` field is the same as the
|
/// If it contains a value, the validation will check that the `sub` field is the same as the
|
||||||
/// one provided and will error otherwise.
|
/// one provided and will error otherwise.
|
||||||
///
|
///
|
||||||
/// Default to `None`.
|
/// Defaults to `None`.
|
||||||
pub sub: Option<String>,
|
pub sub: Option<String>,
|
||||||
|
/// If it contains a value, the validation will check that the `alg` of the header is container
|
||||||
|
/// in the ones provided and will error otherwise.
|
||||||
|
///
|
||||||
|
/// Defaults to `None`.
|
||||||
|
pub algorithms: Option<Vec<Algorithm>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Validation {
|
impl Validation {
|
||||||
|
@ -93,6 +99,8 @@ impl Default for Validation {
|
||||||
iss: None,
|
iss: None,
|
||||||
sub: None,
|
sub: None,
|
||||||
aud: None,
|
aud: None,
|
||||||
|
|
||||||
|
algorithms: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
22
tests/lib.rs
22
tests/lib.rs
|
@ -34,7 +34,7 @@ fn encode_with_custom_header() {
|
||||||
let mut header = Header::default();
|
let mut header = Header::default();
|
||||||
header.kid = Some("kid".to_string());
|
header.kid = Some("kid".to_string());
|
||||||
let token = encode(&header, &my_claims, "secret".as_ref()).unwrap();
|
let token = encode(&header, &my_claims, "secret".as_ref()).unwrap();
|
||||||
let token_data = decode::<Claims>(&token, "secret".as_ref(), Algorithm::HS256, &Validation::default()).unwrap();
|
let token_data = decode::<Claims>(&token, "secret".as_ref(), &Validation::default()).unwrap();
|
||||||
assert_eq!(my_claims, token_data.claims);
|
assert_eq!(my_claims, token_data.claims);
|
||||||
assert_eq!("kid", token_data.header.kid.unwrap());
|
assert_eq!("kid", token_data.header.kid.unwrap());
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ fn round_trip_claim() {
|
||||||
company: "ACME".to_string()
|
company: "ACME".to_string()
|
||||||
};
|
};
|
||||||
let token = encode(&Header::default(), &my_claims, "secret".as_ref()).unwrap();
|
let token = encode(&Header::default(), &my_claims, "secret".as_ref()).unwrap();
|
||||||
let token_data = decode::<Claims>(&token, "secret".as_ref(), Algorithm::HS256, &Validation::default()).unwrap();
|
let token_data = decode::<Claims>(&token, "secret".as_ref(), &Validation::default()).unwrap();
|
||||||
assert_eq!(my_claims, token_data.claims);
|
assert_eq!(my_claims, token_data.claims);
|
||||||
assert!(token_data.header.kid.is_none());
|
assert!(token_data.header.kid.is_none());
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ fn round_trip_claim() {
|
||||||
#[test]
|
#[test]
|
||||||
fn decode_token() {
|
fn decode_token() {
|
||||||
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUifQ.I1BvFoHe94AFf09O6tDbcSB8-jp8w6xZqmyHIwPeSdY";
|
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUifQ.I1BvFoHe94AFf09O6tDbcSB8-jp8w6xZqmyHIwPeSdY";
|
||||||
let claims = decode::<Claims>(token, "secret".as_ref(), Algorithm::HS256, &Validation::default());
|
let claims = decode::<Claims>(token, "secret".as_ref(), &Validation::default());
|
||||||
claims.unwrap();
|
claims.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ fn decode_token() {
|
||||||
#[should_panic(expected = "InvalidToken")]
|
#[should_panic(expected = "InvalidToken")]
|
||||||
fn decode_token_missing_parts() {
|
fn decode_token_missing_parts() {
|
||||||
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9";
|
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9";
|
||||||
let claims = decode::<Claims>(token, "secret".as_ref(), Algorithm::HS256, &Validation::default());
|
let claims = decode::<Claims>(token, "secret".as_ref(), &Validation::default());
|
||||||
claims.unwrap();
|
claims.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,36 +70,36 @@ fn decode_token_missing_parts() {
|
||||||
#[should_panic(expected = "InvalidSignature")]
|
#[should_panic(expected = "InvalidSignature")]
|
||||||
fn decode_token_invalid_signature() {
|
fn decode_token_invalid_signature() {
|
||||||
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUifQ.wrong";
|
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUifQ.wrong";
|
||||||
let claims = decode::<Claims>(token, "secret".as_ref(), Algorithm::HS256, &Validation::default());
|
let claims = decode::<Claims>(token, "secret".as_ref(), &Validation::default());
|
||||||
claims.unwrap();
|
claims.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "WrongAlgorithmHeader")]
|
#[should_panic(expected = "InvalidAlgorithm")]
|
||||||
fn decode_token_wrong_algorithm() {
|
fn decode_token_wrong_algorithm() {
|
||||||
let token = "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUifQ.pKscJVk7-aHxfmQKlaZxh5uhuKhGMAa-1F5IX5mfUwI";
|
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUifQ.I1BvFoHe94AFf09O6tDbcSB8-jp8w6xZqmyHIwPeSdY";
|
||||||
let claims = decode::<Claims>(token, "secret".as_ref(), Algorithm::HS256, &Validation::default());
|
let claims = decode::<Claims>(token, "secret".as_ref(), &Validation {algorithms: Some(vec![Algorithm::RS512]), ..Validation::default()});
|
||||||
claims.unwrap();
|
claims.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn decode_token_with_bytes_secret() {
|
fn decode_token_with_bytes_secret() {
|
||||||
let token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiY29tcGFueSI6Ikdvb2dvbCJ9.27QxgG96vpX4akKNpD1YdRGHE3_u2X35wR3EHA2eCrs";
|
let token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiY29tcGFueSI6Ikdvb2dvbCJ9.27QxgG96vpX4akKNpD1YdRGHE3_u2X35wR3EHA2eCrs";
|
||||||
let claims = decode::<Claims>(token, b"\x01\x02\x03", Algorithm::HS256, &Validation::default());
|
let claims = decode::<Claims>(token, b"\x01\x02\x03", &Validation::default());
|
||||||
assert!(claims.is_ok());
|
assert!(claims.is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn decode_token_with_shuffled_header_fields() {
|
fn decode_token_with_shuffled_header_fields() {
|
||||||
let token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjb21wYW55IjoiMTIzNDU2Nzg5MCIsInN1YiI6IkpvaG4gRG9lIn0.SEIZ4Jg46VGhquuwPYDLY5qHF8AkQczF14aXM3a2c28";
|
let token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjb21wYW55IjoiMTIzNDU2Nzg5MCIsInN1YiI6IkpvaG4gRG9lIn0.SEIZ4Jg46VGhquuwPYDLY5qHF8AkQczF14aXM3a2c28";
|
||||||
let claims = decode::<Claims>(token, "secret".as_ref(), Algorithm::HS256, &Validation::default());
|
let claims = decode::<Claims>(token, "secret".as_ref(), &Validation::default());
|
||||||
assert!(claims.is_ok());
|
assert!(claims.is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn decode_without_validating_signature() {
|
fn decode_without_validating_signature() {
|
||||||
let token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjb21wYW55IjoiMTIzNDU2Nzg5MCIsInN1YiI6IkpvaG4gRG9lIn0.S";
|
let token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjb21wYW55IjoiMTIzNDU2Nzg5MCIsInN1YiI6IkpvaG4gRG9lIn0.S";
|
||||||
let claims = decode::<Claims>(token, "secret".as_ref(), Algorithm::HS256, &Validation {validate_signature: false, ..Validation::default()});
|
let claims = decode::<Claims>(token, "secret".as_ref(), &Validation {validate_signature: false, ..Validation::default()});
|
||||||
assert!(claims.is_ok());
|
assert!(claims.is_ok());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ fn round_trip_claim() {
|
||||||
company: "ACME".to_string()
|
company: "ACME".to_string()
|
||||||
};
|
};
|
||||||
let token = encode(&Header::new(Algorithm::RS256), &my_claims, include_bytes!("private_rsa_key.der")).unwrap();
|
let token = encode(&Header::new(Algorithm::RS256), &my_claims, include_bytes!("private_rsa_key.der")).unwrap();
|
||||||
let token_data = decode::<Claims>(&token, include_bytes!("public_rsa_key.der"), Algorithm::RS256, &Validation::default()).unwrap();
|
let token_data = decode::<Claims>(&token, include_bytes!("public_rsa_key.der"), &Validation::default()).unwrap();
|
||||||
assert_eq!(my_claims, token_data.claims);
|
assert_eq!(my_claims, token_data.claims);
|
||||||
assert!(token_data.header.kid.is_none());
|
assert!(token_data.header.kid.is_none());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue