소스 검색

feat(auth): return expires_at with tokens

Bryan Lee 1 년 전
부모
커밋
e36e87051f

+ 8 - 3
authentication/src/auth/identity.rs

@@ -1,3 +1,4 @@
+use crate::auth::Token;
 use crate::user::User;
 use actix_web::{error, http, web, FromRequest, HttpMessage};
 use chrono::{Duration, Utc};
@@ -62,16 +63,20 @@ impl Identity {
         }
     }
 
-    pub fn generate_token(&self, config: &IdentityConfig) -> String {
+    pub fn generate_token(&self, config: &IdentityConfig) -> Token {
         let now = Utc::now();
         let iat = now.timestamp() as u64;
-        let exp = (now + config.expires_in).timestamp() as u64;
+        let expires_at = now + config.expires_in;
+        let exp = expires_at.timestamp() as u64;
         let claims = IdentityClaims {
             sub: self.user_id,
             iat,
             exp,
         };
-        claims.encode(config)
+        Token {
+            value: claims.encode(config),
+            expires_at,
+        }
     }
 }
 

+ 21 - 4
authentication/src/auth/mod.rs

@@ -6,6 +6,7 @@ pub mod token;
 
 use crate::user::UserWithAuthProviders;
 use actix_web::{cookie, post, web, HttpResponse, Responder};
+use chrono::{DateTime, Utc};
 use serde::Serialize;
 
 pub fn config_service(cfg: &mut web::ServiceConfig) {
@@ -16,19 +17,35 @@ pub fn config_service(cfg: &mut web::ServiceConfig) {
 
 #[post("/sign-out/")]
 async fn sign_out(_: identity::Identity) -> impl Responder {
-    let logout_cookie = cookie::Cookie::build("access_token", "")
+    let clear_access = cookie::Cookie::build("access_token", "")
         .path("/")
         .max_age(cookie::time::Duration::seconds(-1))
         .http_only(true)
         .finish();
 
-    HttpResponse::Ok().cookie(logout_cookie).finish()
+    let clear_refresh = cookie::Cookie::build("refresh_token", "")
+        .path("/")
+        .max_age(cookie::time::Duration::seconds(-1))
+        .http_only(true)
+        .finish();
+
+    HttpResponse::Ok()
+        .cookie(clear_access)
+        .cookie(clear_refresh)
+        .finish()
 }
 
 #[derive(Debug, Clone, Serialize)]
 #[cfg_attr(test, derive(serde::Deserialize, PartialEq))]
 pub struct SignInSuccess {
-    access_token: String,
-    refresh_token: String,
+    access_token: Token,
+    refresh_token: Token,
     user: UserWithAuthProviders,
 }
+
+#[derive(Debug, Clone, Serialize)]
+#[cfg_attr(test, derive(serde::Deserialize, PartialEq))]
+pub struct Token {
+    pub value: String,
+    pub expires_at: DateTime<Utc>,
+}

+ 2 - 2
authentication/src/auth/oauth2/sign_in.rs

@@ -109,7 +109,7 @@ async fn generate_sign_in_success_response(
         user_id: user_with_providers.user.id,
     };
     let access_token = identity.generate_token(identity_config);
-    let sign_in_cookie = cookie::Cookie::build("access_token", access_token.to_owned())
+    let sign_in_cookie = cookie::Cookie::build("access_token", access_token.value.to_owned())
         .path("/")
         .max_age(cookie::time::Duration::seconds(
             identity_config.expires_in.num_seconds(),
@@ -122,7 +122,7 @@ async fn generate_sign_in_success_response(
             .await
             .map_err(error::ErrorInternalServerError)?;
     let refresh_token = refresh_session.generate_token(&identity_config);
-    let refresh_cookie = cookie::Cookie::build("refresh_token", refresh_token.to_owned())
+    let refresh_cookie = cookie::Cookie::build("refresh_token", refresh_token.value.to_owned())
         .path("/")
         .max_age(cookie::time::Duration::seconds(
             identity_config.refresh_expires_in.num_seconds(),

+ 14 - 10
authentication/src/auth/refresh/session.rs

@@ -1,4 +1,5 @@
 use crate::auth::identity::{Identity, IdentityConfig};
+use crate::auth::Token;
 use crate::db::{DbConnection, DbError};
 use crate::{diesel_insertable, schema};
 use actix_web::error;
@@ -57,8 +58,11 @@ impl RefreshSession {
         Ok(token)
     }
 
-    pub fn generate_token(&self, config: &IdentityConfig) -> String {
-        RefreshTokenClaims::from(self).encode(config)
+    pub fn generate_token(&self, config: &IdentityConfig) -> Token {
+        Token {
+            value: RefreshTokenClaims::from(self).encode(config),
+            expires_at: self.expires_at,
+        }
     }
 }
 
@@ -76,8 +80,8 @@ pub enum RefreshResult {
 #[derive(Debug, Clone, Serialize)]
 #[cfg_attr(test, derive(PartialEq))]
 pub struct RefreshSuccess {
-    pub access_token: String,
-    pub refresh_token: String,
+    pub access_token: Token,
+    pub refresh_token: Token,
 }
 
 impl RefreshSession {
@@ -346,7 +350,7 @@ mod tests {
             };
 
             let refresh_result =
-                RefreshSession::refresh(&mut conn, &identity_config, &refresh_token)
+                RefreshSession::refresh(&mut conn, &identity_config, &refresh_token.value)
                     .await
                     .expect("Failed to refresh session");
 
@@ -397,7 +401,7 @@ mod tests {
             };
 
             let refresh_result =
-                RefreshSession::refresh(&mut conn, &identity_config, &refresh_token)
+                RefreshSession::refresh(&mut conn, &identity_config, &refresh_token.value)
                     .await
                     .expect("Failed to refresh session");
 
@@ -449,12 +453,12 @@ mod tests {
                 session.generate_token(identity_config)
             };
 
-            let _ = RefreshSession::refresh(&mut conn, &identity_config, &refresh_token)
+            let _ = RefreshSession::refresh(&mut conn, &identity_config, &refresh_token.value)
                 .await
                 .expect("Failed to refresh session");
 
             let refresh_result =
-                RefreshSession::refresh(&mut conn, &identity_config, &refresh_token)
+                RefreshSession::refresh(&mut conn, &identity_config, &refresh_token.value)
                     .await
                     .expect("Failed to refresh session");
 
@@ -514,7 +518,7 @@ mod tests {
             };
 
             let refresh_result =
-                RefreshSession::refresh(&mut conn, &identity_config, &refresh_token)
+                RefreshSession::refresh(&mut conn, &identity_config, &refresh_token.value)
                     .await
                     .expect("Failed to refresh session");
 
@@ -574,7 +578,7 @@ mod tests {
             };
 
             let refresh_result =
-                RefreshSession::refresh(&mut conn, &identity_config, &refresh_token)
+                RefreshSession::refresh(&mut conn, &identity_config, &refresh_token.value)
                     .await
                     .expect("Failed to refresh session");
 

+ 6 - 2
authentication/src/user/me.rs

@@ -85,7 +85,9 @@ mod tests {
         let pool = web::Data::new(pool);
         let identity_config = web::Data::new(config::get_identity_config());
 
-        let token = Identity::from_user(&user).generate_token(&identity_config);
+        let token = Identity::from_user(&user)
+            .generate_token(&identity_config)
+            .value;
 
         let app = test::init_service(
             App::new()
@@ -174,7 +176,9 @@ mod tests {
         let pool = web::Data::new(pool);
         let identity_config = web::Data::new(config::get_identity_config());
 
-        let token = Identity::from_user(&user).generate_token(&identity_config);
+        let token = Identity::from_user(&user)
+            .generate_token(&identity_config)
+            .value;
 
         let app = test::init_service(
             App::new()