3 unstable releases
0.2.0 | May 17, 2024 |
---|---|
0.1.2 | Dec 28, 2023 |
0.1.1 | Dec 28, 2023 |
#587 in Network programming
45,290 downloads per month
26KB
370 lines
tower-sessions-dynamodb-store
A tower-sessions backend for AWS DynamoDB
Overview
This create provides an AWS DynamoDB back-end for the tower-session session management crate, using the Rust AWS-SDK.
Usage
Setting a DynamoDBStore
requires two parameters:
- An
aws_sdk_dynamodb::Client
instance, for connecting to the AWS DynamoDB service. - A
DynamoDBStoreProps
instance, to tell the Session Store where in dynamo to find/save things.
aws_sdk_dynamodb::Client
There are many possibilities for Setting up a aws_sdk_dynamodb::Client
but all will require an instance of
aws_config::Config
. A most basic example of how to obtain an aws_sdk_dynamodb::Client
instance can be found
from the aws_config rustdocs along with many other examples:
use aws_config;
use aws_sdk_dynamodb;
let config = aws_config::load_defaults(aws_config::BehaviorVersion::v2023_11_09()).await;
let client = aws_sdk_dynamodb::Client::new(&config);
DynamoDBStoreProps
DynamoDBStoreProps
implements the Default trait, so a minimal instance that makes several assumptions about the
DynamoDB table and property names can be obtained using DynamoDBStoreProps::default()
; however it is far more likely you
will need to overwrite one or more of these settings; a more complex example:
let store_props = DynamoDBStoreProps {
table_name: "MyTowerSessions".to_string(),
sort_key: Some(DynamoDBStoreKey {
name: "sort_key".to_string(),
prefix: Some("TOWER_SESSIONS::".to_string()),
suffix: None,
}),
..Default::default()
};
Will create a store props instance that:
- uses the defined DynamoDB Table named
MyTowerSession
. - uses the default
partition_key
name ofsession_id
, and prepends the prefix ofSESSIONS::TOWER::
to all tower session IDs before inserting intosession_id
partition key property. - uses the defined
sort_key
with the same property name ofsort_key
, and prepends the prefix ofTOWER_SESSIONS::
to the session_id before inserting intosort_key
range key property. - uses the default
expirey_name
property name ofexpire_at
to hold the unix timestamp for when the tower-sessions session will expire. - uses the default
data_name
property name ofdata
to hold the binary serialization of the tower-sessions key-value session data.
All items can be overwritten safely, with the only current assumption of your DynamoDB table is that the Partition Key and Range Key properties are both of type S (String).
DynamoDBStore
Once you have instances of aws_sdk_dynamodb::Client
and DynamoDBStoreProps
created, a DynamoDBStore
instance
can be configured and passed to the tower-sessions session manager:
use axum::{response::IntoResponse, routing::get, Router};
use time::Duration;
use tower_sessions::{Expiry, SessionManagerLayer};
use tower_sessions_dynamodb_store::DynamoDBStore;
let session_store = DynamoDBStore::new(client, store_props);
let session_layer = SessionManagerLayer::new(session_store)
.with_secure(false) // only for local testing !!
.with_expiry(Expiry::OnInactivity(Duration::seconds(10)));
let app = Router::new().route("/", get(handler)).layer(session_layer);
You can find a complete example in the example directory.
Examples
Counter
Counter example (using dynamodb-local via docker)
docker compose up dynamodb_store
cargo run --example counter
Once dynamodb-local is running open a browser to http://localhost:3000/ if working correctly, the counter should increment, and a cookie should be visible in the browsers cookie store.
CloudFormation
There is an example AWS CloudFormation template for creating an AWS DynamoDB Table configured to work using the DynamoDBStoreProps::default()
settings.
aws cloudformation create-stack --stack-name ExampleTowerSessionsStack --template-body file:///$PWD/examples/example-table-cfn.yml
Additionally this template illustrates the use of the TimeToLiveSpecification
setting on the expire_at
property,
configuring DynamoDB to remove expired sessions automatically.
Building
rustfmt
cargo fmt --all --check
clippy
cargo clippy --workspace --all-targets --all-features -- -D warnings
rustdoc
RUSTDOCFLAGS="-D rustdoc::broken-intra-doc-links" cargo doc --all-features --no-deps
Dependencies
~20–28MB
~378K SLoC