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
|
use argon2::{
Argon2, PasswordHash, PasswordVerifier,
password_hash::{PasswordHasher, SaltString, rand_core::OsRng},
};
use jsonwebtoken::{self as jwt, DecodingKey, EncodingKey, Header, Validation};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub struct JwtClaims {
pub sub: i64,
pub iat: i64,
pub exp: i64,
}
pub fn create_password(password: &str) -> argon2::password_hash::Result<String> {
Ok(Argon2::default()
.hash_password(password.as_bytes(), &SaltString::generate(&mut OsRng))?
.to_string())
}
pub fn validate_password(
password: &str,
password_hash: &str,
) -> argon2::password_hash::Result<bool> {
Ok(Argon2::default()
.verify_password(password.as_bytes(), &PasswordHash::new(password_hash)?)
.is_ok())
}
pub fn create_jwt(claims: &JwtClaims, secret: &str) -> jwt::errors::Result<String> {
jwt::encode(
&Header::default(),
claims,
&EncodingKey::from_secret(secret.as_bytes()),
)
}
pub fn validate_jwt(token: &str, secret: &str) -> jwt::errors::Result<JwtClaims> {
let mut validation = Validation::default();
validation.set_required_spec_claims(&["exp"]);
validation.validate_exp = true;
validation.leeway = 0;
Ok(jwt::decode(
token,
&DecodingKey::from_secret(secret.as_bytes()),
&validation,
)?
.claims)
}
|