-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtoken_generator.rs
More file actions
127 lines (111 loc) · 3.6 KB
/
token_generator.rs
File metadata and controls
127 lines (111 loc) · 3.6 KB
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
/**
* FCS API - Token Generator (Rust)
*
* Generate secure tokens for frontend JavaScript authentication
*
* Usage:
* 1. Set your access_key and public_key
* 2. Call generate_token()
* 3. Pass the token data to your frontend JavaScript
*
* Add to Cargo.toml:
* [dependencies]
* hmac = "0.12"
* sha2 = "0.10"
* hex = "0.4"
* serde = { version = "1.0", features = ["derive"] }
* serde_json = "1.0"
*
* @package FcsApi
* @author FCS API <support@fcsapi.com>
* @link https://fcsapi.com
*/
use hmac::{Hmac, Mac};
use sha2::Sha256;
use serde::{Deserialize, Serialize};
use std::time::{SystemTime, UNIX_EPOCH};
type HmacSha256 = Hmac<Sha256>;
#[derive(Debug, Serialize, Deserialize)]
pub struct TokenData {
#[serde(rename = "_token")]
pub token: String,
#[serde(rename = "_expiry")]
pub expiry: u64,
#[serde(rename = "_public_key")]
pub public_key: String,
}
/// Token generator for FCS API
/// Token expiry options (in seconds): 300 (5min), 900 (15min), 1800 (30min), 3600 (1hr), 86400 (24hr)
pub struct TokenGenerator {
access_key: String,
public_key: String,
token_expiry: u64,
}
impl TokenGenerator {
/// Create a new token generator
pub fn new(access_key: &str, public_key: &str, token_expiry: Option<u64>) -> Self {
TokenGenerator {
access_key: access_key.to_string(),
public_key: public_key.to_string(),
token_expiry: token_expiry.unwrap_or(3600),
}
}
/// Generate token for frontend authentication
pub fn generate_token(&self) -> TokenData {
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_secs();
let expiry = now + self.token_expiry;
let message = format!("{}{}", self.public_key, expiry);
let mut mac = HmacSha256::new_from_slice(self.access_key.as_bytes())
.expect("HMAC can take key of any size");
mac.update(message.as_bytes());
let result = mac.finalize();
let token = hex::encode(result.into_bytes());
TokenData {
token,
expiry,
public_key: self.public_key.clone(),
}
}
/// Generate token and return as JSON string
pub fn to_json(&self) -> String {
let token_data = self.generate_token();
serde_json::to_string(&token_data).unwrap()
}
/// Generate HTML meta tags for token
pub fn get_meta_tags(&self) -> String {
let token_data = self.generate_token();
format!(
r#"<meta name="fcs-public-key" content="{}">
<meta name="fcs-token" content="{}">
<meta name="fcs-token-expiry" content="{}">"#,
token_data.public_key, token_data.token, token_data.expiry
)
}
}
// ============================================
// USAGE EXAMPLES
// ============================================
fn main() {
// Example 1: Generate token
let generator = TokenGenerator::new("your_access_key", "your_public_key", None);
let token_data = generator.generate_token();
println!("Token Data: {:?}", token_data);
// Example 2: Get as JSON
println!("\nJSON: {}", generator.to_json());
// Example 3: Get meta tags
println!("\nMeta Tags:\n{}", generator.get_meta_tags());
}
// Actix-web example:
// use actix_web::{web, App, HttpServer, HttpResponse};
//
// async fn get_fcs_token() -> HttpResponse {
// let generator = TokenGenerator::new(
// &std::env::var("FCS_ACCESS_KEY").unwrap(),
// &std::env::var("FCS_PUBLIC_KEY").unwrap(),
// None,
// );
// HttpResponse::Ok().json(generator.generate_token())
// }