diff --git a/actix-session/src/lib.rs b/actix-session/src/lib.rs index 31665e524..53f5a7b49 100644 --- a/actix-session/src/lib.rs +++ b/actix-session/src/lib.rs @@ -28,7 +28,7 @@ provided by `actix-session`; it takes care of all the session cookie handling an against the active [`Session`]. `actix-session` provides some built-in storage backends: ([`CookieSessionStore`], -[`RedisSessionStore`], and [`RedisActorSessionStore`]) - you can create a custom storage backend +[`RedisSessionStore`], [`RedisActorSessionStore`], and [`DynamoDbSessionStore`]) - you can create a custom storage backend by implementing the [`SessionStore`] trait. Further reading on sessions: @@ -133,12 +133,22 @@ attached to your sessions. You can enable: actix-session = { version = "...", features = ["redis-rs-session", "redis-rs-tls-session"] } ``` +- a DynamoDB-based backend via [`dynamo-db`](https://docs.rs/aws-sdk-dynamodb), [`DynamoDbSessionStore`], using + the `dynamo-db` feature flag. + + ```toml + [dependencies] + # ... + actix-session = { version = "...", features = ["dynamo-db"] } + ``` + You can implement your own session storage backend using the [`SessionStore`] trait. [`SessionStore`]: storage::SessionStore [`CookieSessionStore`]: storage::CookieSessionStore [`RedisSessionStore`]: storage::RedisSessionStore [`RedisActorSessionStore`]: storage::RedisActorSessionStore +[`DynamoDbSessionStore`]: storage::DynamoDbSessionStore */ #![forbid(unsafe_code)] diff --git a/actix-session/src/storage/dynamo_db.rs b/actix-session/src/storage/dynamo_db.rs index 98a6a9425..0475cb41f 100644 --- a/actix-session/src/storage/dynamo_db.rs +++ b/actix-session/src/storage/dynamo_db.rs @@ -17,6 +17,52 @@ use crate::storage::{ SessionStore, }; +/// Use DynamoDB as session storage backend. +/// +/// ```no_run +/// use actix_web::{web, App, HttpServer, HttpResponse, Error}; +/// use actix_session::{SessionMiddleware, storage::DynamoDbSessionStore}; +/// use actix_web::cookie::Key; +/// use aws_config::meta::region::RegionProviderChain; +/// use aws_config::Region; +/// use aws_config::default_provider::credentials::DefaultCredentialsChain; +/// use aws_sdk_dynamodb::config::ProvideCredentials; +/// use aws_sdk_dynamodb::Client; +/// +/// +/// // The secret key would usually be read from a configuration file/environment variables. +/// fn get_secret_key() -> Key { +/// # todo!() +/// // [...] +/// } +/// +/// #[actix_web::main] +/// async fn main() -> std::io::Result<()> { +/// let secret_key = get_secret_key(); +/// +/// let dynamo_db_store = DynamoDbSessionStore::builder() +/// .table_name(String::from("MyTableName")) +/// .key_name("PK".to_string()) +/// .build() +/// .await?; +/// +/// HttpServer::new(move || +/// App::new() +/// .wrap(SessionMiddleware::new( +/// dynamo_db_store.clone(), +/// secret_key.clone() +/// )) +/// .default_service(web::to(|| HttpResponse::Ok()))) +/// .bind(("127.0.0.1", 8080))? +/// .run() +/// .await +/// } +/// ``` +/// +/// # Implementation notes +/// `DynamoDbSessionStore` leverages [`aws-sdk-dynamodb`] as a DynamoDB client. +/// +/// [`aws-sdk-dynamodb`]: https://github.com/awslabs/aws-sdk-rust #[derive(Clone)] pub struct DynamoDbSessionStore { configuration: CacheConfiguration, @@ -60,7 +106,7 @@ impl DynamoDbSessionStore { /// As a default, it expects a DynamoDB table name of 'sessions', with a single partition key of 'SessionId' this can be overridden using the [`DynamoDbSessionStoreBuilder`]. pub fn builder() -> DynamoDbSessionStoreBuilder { DynamoDbSessionStoreBuilder { - configuration: CacheConfiguration::default(), + configuration: CacheConfiguration::default() } } @@ -76,7 +122,7 @@ impl DynamoDbSessionStore { /// [`DynamoDbSessionStore`]: crate::storage::DynamoDbSessionStore #[must_use] pub struct DynamoDbSessionStoreBuilder { - configuration: CacheConfiguration, + configuration: CacheConfiguration } impl DynamoDbSessionStoreBuilder { @@ -99,6 +145,27 @@ impl DynamoDbSessionStoreBuilder { self } + /// Set the credentials to use for the DynamoDB client. + pub fn with_credentials(mut self, credentials: Credentials) -> Self { + self.configuration.credentials = Some(credentials); + + self + } + + /// Set the SDK config to use for the DynamoDB client. + pub fn with_sdk_config(mut self, config: Config) -> Self { + self.configuration.sdk_config = Some(config); + + self + } + + /// Set the region to use for the DynamoDB client. + pub fn with_region(mut self, region: Region) -> Self { + self.configuration.region = Some(region); + + self + } + /// Set the endpoint to use if using DynamoDB Local. Defaults to 'http://localhost:8000'. pub fn dynamo_db_local_endpoint(mut self, dynamo_db_local_endpoint: String) -> Self { self.configuration.dynamo_db_local_endpoint = dynamo_db_local_endpoint; diff --git a/actix-session/src/storage/mod.rs b/actix-session/src/storage/mod.rs index 33046733f..a194813d6 100644 --- a/actix-session/src/storage/mod.rs +++ b/actix-session/src/storage/mod.rs @@ -20,7 +20,7 @@ mod redis_rs; #[cfg(any(feature = "redis-actor-session", feature = "redis-rs-session"))] mod utils; -#[cfg(any(feature = "dynamo-db"))] +#[cfg(feature = "dynamo-db")] mod dynamo_db; #[cfg(feature = "cookie-session")]