1use std::time::Duration;
2use chrono::{DateTime, Utc};
3use serde::{Deserialize, Serialize};
4pub use jsonwebtoken::*;
5pub use chrono;
6
7pub type TokenResult<T> = errors::Result<T>;
8
9#[derive(Serialize, Deserialize)]
10pub struct Payload<T> {
11 #[serde(skip_serializing_if = "Option::is_none")]
12 pub iss: Option<String>, #[serde(skip_serializing_if = "Option::is_none")]
14 pub exp: Option<u64>, #[serde(skip_serializing_if = "Option::is_none")]
16 pub sub: Option<String>, #[serde(skip_serializing_if = "Option::is_none")]
18 pub aud: Option<String>, #[serde(skip_serializing_if = "Option::is_none")]
20 pub nbf: Option<u64>, #[serde(skip_serializing_if = "Option::is_none")]
22 pub iat: Option<u64>, #[serde(skip_serializing_if = "Option::is_none")]
24 pub jti: Option<u64>, pub data: T,
26}
27
28impl<T> Payload<T> {
29 pub fn is_expire(&self) -> bool {
30 if let Some(exp) = self.exp {
31 let now = Utc::now().timestamp();
32 exp < now as u64
33 } else {
34 false
35 }
36 }
37}
38
39pub struct JsonWebToken;
40
41impl JsonWebToken {
42 pub fn encode<T: Serialize>(alg: Algorithm, data: T, expired_at: DateTime<Utc>, key: &EncodingKey) -> TokenResult<String> {
43 let header = Header::new(alg);
44
45 let payload = Payload {
46 iss: None,
47 exp: Some(expired_at.timestamp() as u64),
48 sub: None,
49 aud: None,
50 nbf: None,
51 iat: None,
52 jti: None,
53 data,
54 };
55 jsonwebtoken::encode(&header, &payload, key)
56 }
57
58 pub fn decode<T: for<'a> Deserialize<'a>>(token: &str, key: &DecodingKey) -> TokenResult<T> {
59 let header = jsonwebtoken::decode_header(token)?;
60 let mut val = Validation::new(header.alg);
61 val.validate_exp = true;
62 let token_data: TokenData<Payload<T>> = jsonwebtoken::decode(token, key, &val)?;
63 Ok(token_data.claims.data)
64 }
65
66 pub fn decode_payload<T: for<'a> Deserialize<'a>>(token: &str, key: &DecodingKey) -> TokenResult<Payload<T>> {
67 let header = jsonwebtoken::decode_header(token)?;
68 let mut val = Validation::new(header.alg);
69 val.validate_exp = true;
70 let token_data: TokenData<Payload<T>> = jsonwebtoken::decode(token, key, &val)?;
71 Ok(token_data.claims)
72 }
73}
74
75pub struct JWTBuilder<T: Serialize> {
76 payload: Payload<T>
77}
78
79impl<T: Serialize> JWTBuilder<T> {
80 pub fn new(data: T) -> Self {
81 Self {
82 payload: Payload {
83 iss: None,
84 exp: None,
85 sub: None,
86 aud: None,
87 nbf: None,
88 iat: None,
89 jti: None,
90 data,
91 }
92 }
93 }
94
95 pub fn iss(mut self, iss: String) -> Self {
96 self.payload.iss = Some(iss);
97 self
98 }
99
100 pub fn exp(mut self, exp: DateTime<Utc>) -> Self {
101 self.payload.exp = Some(exp.timestamp() as u64);
102 self
103 }
104
105 pub fn sub(mut self, sub: String) -> Self {
106 self.payload.sub = Some(sub);
107 self
108 }
109
110 pub fn aud(mut self, aud: String) -> Self {
111 self.payload.aud = Some(aud);
112 self
113 }
114
115 pub fn nbf(mut self, nbf: DateTime<Utc>) -> Self {
116 self.payload.nbf = Some(nbf.timestamp() as u64);
117 self
118 }
119
120 pub fn iat(mut self, iat: DateTime<Utc>) -> Self {
121 self.payload.iat = Some(iat.timestamp() as u64);
122 self
123 }
124
125 pub fn jti(mut self, jti: u64) -> Self {
126 self.payload.jti = Some(jti);
127 self
128 }
129
130 pub fn build(self, alg: Algorithm, key: &EncodingKey) -> TokenResult<String> {
131 let header = Header::new(alg);
132 jsonwebtoken::encode(&header, &self.payload, key)
133 }
134}