1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
//! Rust implementation of JSON Web Tokens, see https://tools.ietf.org/html/rfc7519
//!
//! # Examples
//!
//! ## Sign
//!
//! ```rust
//! use jwts::Claims;
//! use jwts::jws::{Algorithm, Key, Token};
//!
//! let mut claims = Claims::new();
//! claims.iss = Some("sea".to_owned());
//!
//! let mut token = Token::with_payload(claims);
//!
//! // custom the header like:
//! // token.header.cty = Some("application/example".to_owned());
//!
//! let key = Key::new(b"secret", Algorithm::HS256);
//! let token = token.sign(&key).unwrap_or_default();
//!
//! assert_eq!(token, "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJzZWEifQ.L0DLtDjydcSK-c0gTyOYbmUQ_LUCZzqAGCINn2OLhFs");
//! ```
//!
//! ## Parse and Verify
//!
//! ```rust
//! use jwts::{Claims, jws};
//! use jwts::jws::{Algorithm, Config, Key, SignatureValidation, Token};
//!
//! let key = Key::new(b"secret", Algorithm::HS256);
//! let signature_validation = SignatureValidation::Key(key);
//!
//! // use key resolver like:
//! // let signature_validation = SignatureValidation::KeyResolver(|header, payload| {
//! //     // return a Key here
//! // });
//!
//! let config = Config {
//! signature_validation,
//! iat_validation: true,
//! nbf_validation: true,
//! exp_validation: true,
//! expected_iss: Some("sea".to_owned()),
//! expected_sub: None,
//! expected_aud: None,
//! expected_jti: None,
//! };
//!
//! let token = "a jwt token";
//!
//! let token: Option<Token<Claims>> = jws::parse(token, &config)
//! .map(Option::Some)
//! .unwrap_or_else(|err| {
//! println!("{:?}", err.kind());
//! None
//! });
//! println!("{:?}", token);
//! ```
//!
//! ## Custom Claims
//!
//! ```rust
//! use jwts::{Claims, jws};
//! use jwts::jws::{Algorithm, Key, Token};
//!
//! #[macro_use]
//! extern crate serde_derive;
//!
//! #[derive(Debug, Serialize, Deserialize)]
//! struct CustomClaims {
//! iss: String,
//! }
//!
//! let claims = CustomClaims {
//! iss: "sea".to_owned(),
//! };
//!
//! let mut token = Token::with_payload(claims);
//! let key = Key::new(b"secret", Algorithm::HS256);
//! let token = token.sign(&key).unwrap_or_default();
//! let token: Token<CustomClaims> = jws::parse_validate_none(&token).unwrap();
//! println!("{:?}", token);
//! ```

#[macro_use]
extern crate serde_derive;

pub use crate::error::{Error, ErrorKind};

#[cfg(test)]
mod tests;

pub mod jws;
pub mod error;
mod time;
mod bs64;

/// Registered Claim Names, see https://tools.ietf.org/html/rfc7519#section-4.1
#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
    /// Issuer
    #[serde(skip_serializing_if = "Option::is_none")]
    pub iss: Option<String>,
    /// Subject
    #[serde(skip_serializing_if = "Option::is_none")]
    pub sub: Option<String>,
    /// Audience
    #[serde(skip_serializing_if = "Option::is_none")]
    pub aud: Option<String>,
    /// Expiration Time
    #[serde(skip_serializing_if = "Option::is_none")]
    pub exp: Option<u64>,
    /// Not Before
    #[serde(skip_serializing_if = "Option::is_none")]
    pub nbf: Option<u64>,
    /// Issued At
    #[serde(skip_serializing_if = "Option::is_none")]
    pub iat: Option<u64>,
    /// JWT ID
    #[serde(skip_serializing_if = "Option::is_none")]
    pub jti: Option<String>,
}

impl Claims {

    /// Create a new `Claims`.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use jwts::Claims;
    ///
    /// let mut claims = Claims::new();
    /// ```
    #[inline]
    pub fn new() -> Self {
        Claims {
            iss: None,
            sub: None,
            aud: None,
            exp: None,
            nbf: None,
            iat: None,
            jti: None,
        }
    }
}