Add a method to decode a token without signature validation

- Solves #48
- `dangerous_unsafe_decode`
- No docs (aside from cargo) since people probably shouldn't use it
This commit is contained in:
Mike Engel 2018-03-03 10:50:03 -07:00
parent 99e0a2ed01
commit d30a7599a8
No known key found for this signature in database
GPG Key ID: 225C4F0D1FDE7CF8
2 changed files with 59 additions and 1 deletions

View File

@ -122,6 +122,35 @@ pub fn decode<T: DeserializeOwned>(token: &str, key: &[u8], validation: &Validat
Ok(TokenData { header: header, claims: decoded_claims })
}
/// Decode a token without any signature validation into a struct containing 2 fields: `claims` and `header`.
///
/// NOTE: Do not use this unless you know what you are doing! If the token's signature is invalid, it will *not* return an error.
///
/// ```rust,ignore
/// #[macro_use]
/// extern crate serde_derive;
/// use jsonwebtoken::{dangerous_unsafe_decode, Validation, Algorithm};
///
/// #[derive(Debug, Serialize, Deserialize)]
/// struct Claims {
/// sub: String,
/// company: String
/// }
///
/// let token = "a.jwt.token".to_string();
/// // Claims is a struct that implements Deserialize
/// let token_data = dangerous_unsafe_decode::<Claims>(&token, &Validation::new(Algorithm::HS256));
/// ```
pub fn dangerous_unsafe_decode<T: DeserializeOwned>(token: &str) -> Result<TokenData<T>> {
let (_, signing_input) = expect_two!(token.rsplitn(2, '.'));
let (claims, header) = expect_two!(signing_input.rsplitn(2, '.'));
let header: Header = from_jwt_part(header)?;
let (decoded_claims, _): (T, _) = from_jwt_part_claims(claims)?;
Ok(TokenData { header: header, claims: decoded_claims })
}
/// Decode a token and return the Header. This is not doing any kind of validation: it is meant to be
/// used when you don't know which `alg` the token is using and want to find out.
///

View File

@ -2,7 +2,7 @@ extern crate jsonwebtoken;
#[macro_use]
extern crate serde_derive;
use jsonwebtoken::{encode, decode, decode_header, Algorithm, Header, sign, verify, Validation};
use jsonwebtoken::{encode, decode, decode_header, dangerous_unsafe_decode, Algorithm, Header, sign, verify, Validation};
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
@ -103,3 +103,32 @@ fn decode_header_only() {
assert_eq!(header.alg, Algorithm::HS256);
assert_eq!(header.typ, Some("JWT".to_string()));
}
#[test]
fn dangerous_unsafe_decode_token() {
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUifQ.I1BvFoHe94AFf09O6tDbcSB8-jp8w6xZqmyHIwPeSdY";
let claims = dangerous_unsafe_decode::<Claims>(token);
claims.unwrap();
}
#[test]
#[should_panic(expected = "InvalidToken")]
fn dangerous_unsafe_decode_token_missing_parts() {
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9";
let claims = dangerous_unsafe_decode::<Claims>(token);
claims.unwrap();
}
#[test]
fn dangerous_unsafe_decode_token_invalid_signature() {
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUifQ.wrong";
let claims = dangerous_unsafe_decode::<Claims>(token);
claims.unwrap();
}
#[test]
fn dangerous_unsafe_decode_token_wrong_algorithm() {
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUifQ.I1BvFoHe94AFf09O6tDbcSB8-jp8w6xZqmyHIwPeSdY";
let claims = dangerous_unsafe_decode::<Claims>(token);
claims.unwrap();
}