jwt is added

This commit is contained in:
병준 박 2022-08-08 07:19:22 +00:00
parent a8726765e8
commit 499101855c
8 changed files with 122 additions and 5 deletions

2
.vscode/launch.json vendored
View File

@ -25,6 +25,7 @@
"QUEUE_BROKER": "bet.beteran",
"CAPTCHA_SALT": "!#%&(24680qetuWRYI",
"PASSWORD_SALT": "@$^*)13579wryipQETUO",
"JWT_SECRET": "!@$^*)13579wryipQETUO!",
},
"args": [],
"cwd": "${workspaceFolder}"
@ -51,6 +52,7 @@
"QUEUE_BROKER": "bet.beteran",
"CAPTCHA_SALT": "!#%&(24680qetuWRYI",
"PASSWORD_SALT": "@$^*)13579wryipQETUO",
"JWT_SECRET": "!@$^*)13579wryipQETUO!",
},
"args": [],
"cwd": "${workspaceFolder}"

View File

@ -19,16 +19,18 @@ diesel-derive-enum = { version = "1", features = ["postgres"] }
futures = { version = "0", default-features = false, features = [
"async-await",
] }
jsonwebtoken = { version = "8" }
nats = { version = "0" }
prost = { version = "0" }
rust-argon2 = { version = "1" }
serde = { version = "1", features = ["derive"] }
serde_json = { version = "1" }
time = { version = "0.3" }
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
tokio-cron-scheduler = { version = "0" }
uuid = { version = "0", features = ["serde", "v4", "v5"] }
beteran-protobuf-rust = { git = "https://gitlab.loafle.net/bet/beteran-protobuf-rust.git", tag = "v0.1.24-snapshot" }
beteran-common-rust = { git = "https://gitlab.loafle.net/bet/beteran-common-rust.git", tag = "v0.1.4-snapshot" }
beteran-protobuf-rust = { git = "https://gitlab.loafle.net/bet/beteran-protobuf-rust.git", tag = "v0.1.25-snapshot" }
beteran-common-rust = { git = "https://gitlab.loafle.net/bet/beteran-common-rust.git", tag = "v0.1.5-snapshot" }
[build-dependencies]

View File

@ -0,0 +1,68 @@
//!
//!
use super::models;
use crate::repositories;
use time::{Duration, OffsetDateTime};
pub struct Composition {
jwt_secret: String,
site_repository: repositories::site::repository::Repository,
}
impl std::fmt::Debug for Composition {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.debug_struct("Composition of members").finish()
}
}
impl Composition {
///
pub fn new(jwt_secret: String) -> Composition {
Composition {
jwt_secret,
site_repository: repositories::site::repository::Repository::new(),
}
}
///
pub fn get_token(
&self,
issuer: String,
session_id: String,
) -> Result<String, jsonwebtoken::errors::Error> {
use jsonwebtoken::{encode, Algorithm, EncodingKey, Header};
let header = Header::new(Algorithm::HS512);
let issued_at = OffsetDateTime::now_utc();
let expiration_at = issued_at + Duration::days(1);
let claims = models::Claims {
iss: issuer,
iat: issued_at
.date()
.with_hms_milli(issued_at.hour(), issued_at.minute(), issued_at.second(), 0)
.unwrap()
.assume_utc(),
exp: expiration_at
.date()
.with_hms_milli(
expiration_at.hour(),
expiration_at.minute(),
expiration_at.second(),
0,
)
.unwrap()
.assume_utc(),
session_id,
};
let token = encode(
&header,
&claims,
&EncodingKey::from_secret(self.jwt_secret.as_bytes()),
)?;
Ok(token)
}
}

View File

@ -0,0 +1,7 @@
//!
//!
///
pub mod composition;
///
pub mod models;

View File

@ -0,0 +1,20 @@
use serde::{Deserialize, Serialize};
use time::OffsetDateTime;
// #[derive(Debug, Serialize, Deserialize)]
// struct Claims {
// aud: String, // Optional. Audience
// exp: usize, // Required (validate_exp defaults to true in validation). Expiration time (as UTC timestamp)
// iat: usize, // Optional. Issued at (as UTC timestamp)
// iss: String, // Optional. Issuer
// nbf: usize, // Optional. Not Before (as UTC timestamp)
// sub: String, // Optional. Subject (whom token refers to)
// }
#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
pub iss: String,
pub iat: OffsetDateTime,
pub exp: OffsetDateTime,
pub session_id: String,
}

View File

@ -1,2 +1,3 @@
pub mod identity;
pub mod member;
pub mod site;

View File

@ -42,6 +42,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
Some(v) => v.into_string().unwrap(),
None => "".to_string(),
};
let jwt_secret = match env::var_os("JWT_SECRET") {
Some(v) => v.into_string().unwrap(),
None => "".to_string(),
};
let manager = ConnectionManager::<PgConnection>::new(url_db);
let pool = Pool::builder()
@ -61,6 +65,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
pool.clone(),
captcha_salt.clone(),
password_salt.clone(),
jwt_secret.clone(),
);
println!("Server service [beteran-server-service] is started");

View File

@ -20,6 +20,7 @@ pub struct Service<'a> {
member_session_repository: repositories::member_session::repository::Repository,
site_repository: repositories::site::repository::Repository,
site_composition: compositions::site::composition::Composition,
identity_composition: compositions::identity::composition::Composition,
argon2_config: argon2::Config<'a>,
captcha_salt: String,
password_salt: String,
@ -40,6 +41,7 @@ impl Service<'_> {
pool: Pool<ConnectionManager<PgConnection>>,
captcha_salt: String,
password_salt: String,
jwt_secret: String,
) -> Service<'static> {
Service {
connection_broker,
@ -49,6 +51,7 @@ impl Service<'_> {
member_session_repository: repositories::member_session::repository::Repository::new(),
site_repository: repositories::site::repository::Repository::new(),
site_composition: compositions::site::composition::Composition::new(),
identity_composition: compositions::identity::composition::Composition::new(jwt_secret),
argon2_config: argon2::Config::default(),
captcha_salt,
password_salt,
@ -546,13 +549,22 @@ impl Service<'_> {
})
})?;
let access_token = self
.identity_composition
.get_token("Beteran".to_string(), session.id.to_string())
.map_err(|e| {
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
code: bpr::protobuf::rpc::Error::SERVER_00,
message: format!("server {}", e),
data: None,
})
})?;
message
.respond(
bpr::ss::member::identity::SigninResponse {
error: None,
result: Some(bpr::ss::member::identity::signin_response::Result {
session_id: session.id.to_string(),
}),
result: Some(bpr::ss::member::identity::signin_response::Result { access_token }),
}
.encode_to_vec(),
)