diff --git a/CHANGELOG.md b/CHANGELOG.md index 024e40c..ee940ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,9 +8,9 @@ - Remove deprecated `dangerous_unsafe_decode` - `Validation::iss` is now a `HashSet` instead of a single value - `decode` will now error if `Validation::algorithms` is empty -- Add JWKs types for easy interop with various Oauth providers +- Add JWKs types for easy interop with various Oauth provider, see `examples/auth0.rs` for an example - Removed `decode_*` functions in favour of using the `Validation` struct -- Allow float values for `exp` and `nbf`, yes it's in the spec... floats will be rounded to u64 +- Allow float values for `exp` and `nbf`, yes it's in the spec... floats will be rounded and converted to u64 - Error now implements Clone/Eq - Change default leeway from 0s to 60s diff --git a/README.md b/README.md index a7017ce..fd6efca 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ See [JSON Web Tokens](https://en.wikipedia.org/wiki/JSON_Web_Token) for more inf Add the following to Cargo.toml: ```toml -jsonwebtoken = "7" +jsonwebtoken = "8" serde = {version = "1.0", features = ["derive"] } ``` @@ -51,6 +51,7 @@ struct Claims { ### Claims The claims fields which can be validated. (see [validation](#validation)) + ```rust #[derive(Debug, Serialize, Deserialize)] struct Claims { @@ -162,36 +163,4 @@ you can add some leeway to the `iat`, `exp` and `nbf` validation by setting the Last but not least, you will need to set the algorithm(s) allowed for this token if you are not using `HS256`. -```rust -#[derive(Debug, Clone, PartialEq)] -struct Validation { - pub leeway: u64, // Default: 0 - pub validate_exp: bool, // Default: true - pub validate_nbf: bool, // Default: false - pub aud: Option>, // Default: None - pub iss: Option>, // Default: None - pub sub: Option, // Default: None - pub algorithms: Vec, // Default: vec![Algorithm::HS256] -} -``` - -```rust -use jsonwebtoken::{Validation, Algorithm}; - -// Default validation: the only algo allowed is HS256 -let validation = Validation::default(); -// Quick way to setup a validation where only the algorithm changes -let validation = Validation::new(Algorithm::HS512); -// Adding some leeway (in seconds) for exp and nbf checks -let mut validation = Validation {leeway: 60, ..Default::default()}; -// Checking issuer -let mut iss = std::collections::HashSet::new(); -iss.insert("issuer".to_string()); -let mut validation = Validation {iss: Some(iss), ..Default::default()}; -// Setting audience -let mut validation = Validation::default(); -validation.set_audience(&"Me"); // string -validation.set_audience(&["Me", "You"]); // array of strings -``` - Look at `examples/validation.rs` for a full working example. diff --git a/examples/validation.rs b/examples/validation.rs index 0edc3c2..fdd0c63 100644 --- a/examples/validation.rs +++ b/examples/validation.rs @@ -4,6 +4,7 @@ use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize)] struct Claims { + aud: String, sub: String, company: String, exp: usize, @@ -11,8 +12,12 @@ struct Claims { fn main() { let key = b"secret"; - let my_claims = - Claims { sub: "b@b.com".to_owned(), company: "ACME".to_owned(), exp: 10000000000 }; + let my_claims = Claims { + aud: "me".to_owned(), + sub: "b@b.com".to_owned(), + company: "ACME".to_owned(), + exp: 10000000000, + }; let token = match encode(&Header::default(), &my_claims, &EncodingKey::from_secret(key)) { Ok(t) => t, Err(_) => panic!(), // in practice you would return the error @@ -20,6 +25,7 @@ fn main() { let mut validation = Validation::new(Algorithm::HS256); validation.sub = Some("b@b.com".to_string()); + validation.set_audience(&["me"]); let token_data = match decode::(&token, &DecodingKey::from_secret(key), &validation) { Ok(c) => c, Err(err) => match *err.kind() { diff --git a/src/validation.rs b/src/validation.rs index e9423e7..20f213b 100644 --- a/src/validation.rs +++ b/src/validation.rs @@ -23,8 +23,8 @@ use crate::errors::{new_error, ErrorKind, Result}; /// validation.set_audience(&["Me"]); // a single string /// validation.set_audience(&["Me", "You"]); // array of strings /// // or issuer -/// validation.set_iss(&["Me"]); // a single string -/// validation.set_iss(&["Me", "You"]); // array of strings +/// validation.set_issuer(&["Me"]); // a single string +/// validation.set_issuer(&["Me", "You"]); // array of strings /// ``` #[derive(Debug, Clone, PartialEq)] pub struct Validation { @@ -47,11 +47,13 @@ pub struct Validation { pub validate_nbf: bool, /// If it contains a value, the validation will check that the `aud` field is a member of the /// audience provided and will error otherwise. + /// Use `set_audience` to set it /// /// Defaults to `None`. pub aud: Option>, /// If it contains a value, the validation will check that the `iss` field is a member of the /// iss provided and will error otherwise. + /// Use `set_issuer` to set it /// /// Defaults to `None`. pub iss: Option>, @@ -77,12 +79,14 @@ impl Validation { } /// `aud` is a collection of one or more acceptable audience members + /// The simple usage is `set_audience(&["some aud name"])` pub fn set_audience(&mut self, items: &[T]) { self.aud = Some(items.iter().map(|x| x.to_string()).collect()) } - /// `iss` is a collection of one or more acceptable iss members - pub fn set_iss(&mut self, items: &[T]) { + /// `iss` is a collection of one or more acceptable issuers members + /// The simple usage is `set_issuer(&["some iss name"])` + pub fn set_issuer(&mut self, items: &[T]) { self.iss = Some(items.iter().map(|x| x.to_string()).collect()) } @@ -379,7 +383,7 @@ mod tests { let mut validation = Validation::new(Algorithm::HS256); validation.validate_exp = false; - validation.set_iss(&["Keats"]); + validation.set_issuer(&["Keats"]); let res = validate(deserialize_claims(&claims), &validation); assert!(res.is_ok()); @@ -391,7 +395,7 @@ mod tests { let mut validation = Validation::new(Algorithm::HS256); validation.validate_exp = false; - validation.set_iss(&["Keats"]); + validation.set_issuer(&["Keats"]); let res = validate(deserialize_claims(&claims), &validation); assert!(res.is_err()); @@ -407,7 +411,7 @@ mod tests { let mut validation = Validation::new(Algorithm::HS256); validation.validate_exp = false; - validation.set_iss(&["Keats"]); + validation.set_issuer(&["Keats"]); let res = validate(deserialize_claims(&claims), &validation); match res.unwrap_err().kind() { @@ -528,7 +532,7 @@ mod tests { let mut validation = Validation::new(Algorithm::HS256); validation.leeway = 5; - validation.set_iss(&["iss no check"]); + validation.set_issuer(&["iss no check"]); validation.set_audience(&["iss no check"]); let res = validate(deserialize_claims(&claims), &validation);