1use std::time::Duration;
2use chrono::{DateTime, Utc};
3use serde::{Deserialize, Serialize};
4pub use jsonwebtoken::*;
5
6pub type TokenResult<T> = errors::Result<T>;
7
8#[derive(Serialize, Deserialize)]
9pub struct Payload<T> {
10 #[serde(skip_serializing_if = "Option::is_none")]
11 pub iss: Option<String>, #[serde(skip_serializing_if = "Option::is_none")]
13 pub exp: Option<u64>, #[serde(skip_serializing_if = "Option::is_none")]
15 pub sub: Option<String>, #[serde(skip_serializing_if = "Option::is_none")]
17 pub aud: Option<String>, #[serde(skip_serializing_if = "Option::is_none")]
19 pub nbf: Option<u64>, #[serde(skip_serializing_if = "Option::is_none")]
21 pub iat: Option<u64>, #[serde(skip_serializing_if = "Option::is_none")]
23 pub jti: Option<u64>, pub data: T,
25}
26
27impl<T> Payload<T> {
28 pub fn is_expire(&self, interval: Duration) -> bool {
29 if let Some(exp) = self.exp {
30 let now = Utc::now().timestamp();
31 exp < now as u64 + interval.as_secs()
32 } else {
33 false
34 }
35 }
36}
37
38pub struct JsonWebToken;
39
40impl JsonWebToken {
41 pub fn encode<T: Serialize>(alg: Algorithm, data: T, expired_at: DateTime<Utc>, key: &EncodingKey) -> TokenResult<String> {
42 let header = Header::new(alg);
43
44 let payload = Payload {
45 iss: None,
46 exp: Some(expired_at.timestamp() as u64),
47 sub: None,
48 aud: None,
49 nbf: None,
50 iat: None,
51 jti: None,
52 data,
53 };
54 jsonwebtoken::encode(&header, &payload, key)
55 }
56
57 pub fn decode<T: for<'a> Deserialize<'a>>(token: &str, key: &DecodingKey) -> TokenResult<T> {
58 let header = jsonwebtoken::decode_header(token)?;
59 let mut val = Validation::new(header.alg);
60 val.validate_exp = true;
61 let token_data: TokenData<Payload<T>> = jsonwebtoken::decode(token, key, &val)?;
62 Ok(token_data.claims.data)
63 }
64
65 pub fn decode_payload<T: for<'a> Deserialize<'a>>(token: &str, key: &DecodingKey) -> TokenResult<Payload<T>> {
66 let header = jsonwebtoken::decode_header(token)?;
67 let mut val = Validation::new(header.alg);
68 val.validate_exp = true;
69 let token_data: TokenData<Payload<T>> = jsonwebtoken::decode(token, key, &val)?;
70 Ok(token_data.claims)
71 }
72}