basic_usage/
basic_usage.rs1use common_access_token::{
2 current_timestamp, Algorithm, CborValue, KeyId, RegisteredClaims, TokenBuilder,
3 VerificationOptions,
4};
5use std::collections::BTreeMap;
6
7fn main() {
8 let key = b"my-secret-key-for-hmac-sha256";
10
11 let string_kid_token = create_token_with_string_kid(key);
13 let binary_kid_token = create_token_with_binary_kid(key);
14 let nested_map_token = create_token_with_nested_map(key);
15
16 let string_kid_token_bytes = string_kid_token.to_bytes().expect("Failed to encode token");
18 let binary_kid_token_bytes = binary_kid_token.to_bytes().expect("Failed to encode token");
19 let nested_map_token_bytes = nested_map_token.to_bytes().expect("Failed to encode token");
20
21 println!(
22 "Token with string key ID encoded as {} bytes",
23 string_kid_token_bytes.len()
24 );
25 println!(
26 "Token with binary key ID encoded as {} bytes",
27 binary_kid_token_bytes.len()
28 );
29 println!(
30 "Token with nested map encoded as {} bytes",
31 nested_map_token_bytes.len()
32 );
33
34 verify_token(&string_kid_token_bytes, key, "string-key-example");
36 verify_token(&binary_kid_token_bytes, key, "binary-key-example");
37 verify_nested_map_token(&nested_map_token_bytes, key);
38}
39
40fn create_token_with_string_kid(key: &[u8]) -> common_access_token::Token {
42 let now = current_timestamp();
43
44 TokenBuilder::new()
46 .algorithm(Algorithm::HmacSha256)
47 .protected_key_id(KeyId::string("string-key-example"))
48 .registered_claims(
49 RegisteredClaims::new()
50 .with_issuer("example-issuer")
51 .with_subject("example-subject")
52 .with_audience("example-audience")
53 .with_expiration(now + 3600) .with_not_before(now)
55 .with_issued_at(now)
56 .with_cti(b"token-id-1234".to_vec()),
57 )
58 .custom_string(100, "custom-string-value")
59 .custom_binary(101, b"custom-binary-value".to_vec())
60 .custom_int(102, 12345)
61 .sign(key)
62 .expect("Failed to sign token")
63}
64
65fn create_token_with_binary_kid(key: &[u8]) -> common_access_token::Token {
67 let now = current_timestamp();
68 let binary_kid = vec![0x01, 0x02, 0x03, 0x04, 0x05];
69
70 TokenBuilder::new()
72 .algorithm(Algorithm::HmacSha256)
73 .protected_key_id(KeyId::binary(binary_kid))
74 .registered_claims(
75 RegisteredClaims::new()
76 .with_issuer("example-issuer")
77 .with_subject("example-subject")
78 .with_audience("example-audience")
79 .with_expiration(now + 3600) .with_not_before(now)
81 .with_issued_at(now),
82 )
83 .sign(key)
84 .expect("Failed to sign token")
85}
86
87fn create_token_with_nested_map(key: &[u8]) -> common_access_token::Token {
89 let now = current_timestamp();
90
91 let mut nested_map = BTreeMap::new();
93 nested_map.insert(1, CborValue::Text("nested-text-value".to_string()));
94 nested_map.insert(2, CborValue::Integer(42));
95 nested_map.insert(3, CborValue::Bytes(vec![1, 2, 3, 4, 5]));
96
97 let mut second_level_map = BTreeMap::new();
99 second_level_map.insert(1, CborValue::Text("second-level-text".to_string()));
100 second_level_map.insert(2, CborValue::Integer(99));
101
102 nested_map.insert(4, CborValue::Map(second_level_map));
104
105 TokenBuilder::new()
107 .algorithm(Algorithm::HmacSha256)
108 .protected_key_id(KeyId::string("nested-map-example"))
109 .registered_claims(
110 RegisteredClaims::new()
111 .with_issuer("example-issuer")
112 .with_subject("example-subject")
113 .with_audience("example-audience")
114 .with_expiration(now + 3600) .with_not_before(now)
116 .with_issued_at(now),
117 )
118 .custom_map(200, nested_map)
119 .sign(key)
120 .expect("Failed to sign token")
121}
122
123fn verify_token(token_bytes: &[u8], key: &[u8], expected_token_type: &str) {
125 let token = match common_access_token::Token::from_bytes(token_bytes) {
127 Ok(token) => token,
128 Err(err) => {
129 println!("Failed to decode {} token: {}", expected_token_type, err);
130 return;
131 }
132 };
133
134 if let Err(err) = token.verify(key) {
136 println!(
137 "Failed to verify {} token signature: {}",
138 expected_token_type, err
139 );
140 return;
141 }
142
143 let options = VerificationOptions::new()
145 .verify_exp(true)
146 .verify_nbf(true)
147 .expected_issuer("example-issuer")
148 .expected_audience("example-audience");
149
150 if let Err(err) = token.verify_claims(&options) {
151 println!(
152 "Failed to verify {} token claims: {}",
153 expected_token_type, err
154 );
155 return;
156 }
157
158 let kid = token.header.key_id().expect("No key ID in token");
160 let kid_str = match &kid {
161 KeyId::Binary(data) => format!("Binary key ID: {:?}", data),
162 KeyId::String(data) => format!("String key ID: {}", data),
163 };
164
165 println!(
166 "Successfully verified {} token ({})",
167 expected_token_type, kid_str
168 );
169
170 if let Some(iss) = &token.claims.registered.iss {
172 println!(" Issuer: {}", iss);
173 }
174 if let Some(sub) = &token.claims.registered.sub {
175 println!(" Subject: {}", sub);
176 }
177 if let Some(exp) = token.claims.registered.exp {
178 println!(
179 " Expires at: {} (in {} seconds)",
180 exp,
181 exp - current_timestamp()
182 );
183 }
184}
185
186fn verify_nested_map_token(token_bytes: &[u8], key: &[u8]) {
188 let token = match common_access_token::Token::from_bytes(token_bytes) {
190 Ok(token) => token,
191 Err(err) => {
192 println!("Failed to decode nested map token: {}", err);
193 return;
194 }
195 };
196
197 if let Err(err) = token.verify(key) {
199 println!("Failed to verify nested map token signature: {}", err);
200 return;
201 }
202
203 let options = VerificationOptions::new()
205 .verify_exp(true)
206 .verify_nbf(true)
207 .expected_issuer("example-issuer")
208 .expected_audience("example-audience");
209
210 if let Err(err) = token.verify_claims(&options) {
211 println!("Failed to verify nested map token claims: {}", err);
212 return;
213 }
214
215 println!("Successfully verified nested map token");
216
217 if let Some(CborValue::Map(map)) = token.claims.custom.get(&200) {
219 println!(" Found nested map claim with {} entries", map.len());
220
221 if let Some(CborValue::Text(text)) = map.get(&1) {
223 println!(" Entry 1: Text = {}", text);
224 }
225
226 if let Some(CborValue::Integer(num)) = map.get(&2) {
227 println!(" Entry 2: Integer = {}", num);
228 }
229
230 if let Some(CborValue::Bytes(bytes)) = map.get(&3) {
231 println!(" Entry 3: Bytes = {:?}", bytes);
232 }
233
234 if let Some(CborValue::Map(second_map)) = map.get(&4) {
236 println!(" Entry 4: Nested map with {} entries", second_map.len());
237
238 if let Some(CborValue::Text(text)) = second_map.get(&1) {
239 println!(" Nested Entry 1: Text = {}", text);
240 }
241
242 if let Some(CborValue::Integer(num)) = second_map.get(&2) {
243 println!(" Nested Entry 2: Integer = {}", num);
244 }
245 }
246 } else {
247 println!(" Nested map claim not found!");
248 }
249}