Skip to content

Commit

Permalink
fix(docs): Simplify example code
Browse files Browse the repository at this point in the history
  • Loading branch information
LeoniePhiline committed Nov 23, 2022
1 parent dba0675 commit bd97c0d
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 89 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ homepage = "https://github.com/LeoniePhiline/axum-csrf-sync-pattern"
license = "Apache-2.0"
readme = "README.md"

version = "0.1.0"
version = "0.1.1"
edition = "2021"

[badges]
Expand Down
71 changes: 39 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,37 +91,40 @@ In each example directory, execute `cargo run`, then open [http://127.0.0.1:3000
Configure your session and CSRF protection layer in your backend application:

```rust
use async_session::MemoryStore;
use axum::{
body::Body,
http::StatusCode,
routing::{get, Router},
};
use axum_csrf_sync_pattern::{CsrfSynchronizerTokenLayer, RegenerateToken};
use axum_sessions::SessionLayer;
use rand::RngCore;

let mut secret = [0; 64];
rand::thread_rng().try_fill_bytes(&mut secret).unwrap();

async fn handler() -> axum::http::StatusCode {
axum::http::StatusCode::OK
async fn handler() -> StatusCode {
StatusCode::OK
}

let app = axum::Router::new()
.route("/", axum::routing::get(handler).post(handler))
let app = Router::new()
.route("/", get(handler).post(handler))
.layer(
axum_csrf_sync_pattern::CsrfSynchronizerTokenLayer::default()
CsrfSynchronizerTokenLayer::default()

// Optionally, configure the layer with the following options:

// Default: RegenerateToken::PerSession
.regenerate(axum_csrf_sync_pattern::RegenerateToken::PerUse)
.regenerate(RegenerateToken::PerUse)
// Default: "X-CSRF-TOKEN"
.request_header("X-Custom-CSRF-Token-Client-Request-Header")
.request_header("X-Custom-Request-Header")
// Default: "X-CSRF-TOKEN"
.response_header("X-Custom-CSRF-Token-Server-Response-Header")
.response_header("X-Custom-Response-Header")
// Default: "_csrf_token"
.session_key("_custom_csrf_token_session_key")
.session_key("_custom_session_key")
)
.layer(
axum_sessions::SessionLayer::new(
async_session::MemoryStore::new(),
&secret
)
);
.layer(SessionLayer::new(MemoryStore::new(), &secret));

// Use hyper to run `app` as service and expose on a local port or socket.

Expand All @@ -139,7 +142,7 @@ Receive the token and send same-site requests, using your custom header:
const test = async () => {
// Receive CSRF token (Default response header name: 'X-CSRF-TOKEN')
const token = (await fetch("/")).headers.get(
"X-Custom-CSRF-Token-Server-Response-Header"
"X-Custom-Response-Header"
);

// Submit data using the token
Expand All @@ -148,7 +151,7 @@ const test = async () => {
headers: {
"Content-Type": "application/json",
// Default request header name: 'X-CSRF-TOKEN'
"X-Custom-CSRF-Token-Client-Request-Header": token,
"X-Custom-Request-Header": token,
},
body: JSON.stringify({
/* ... */
Expand All @@ -168,32 +171,36 @@ In each example directory, execute `cargo run`, then open [http://127.0.0.1:3000
Configure your CORS layer, session and CSRF protection layer in your backend application:

```rust
use async_session::MemoryStore;
use axum::{
body::Body,
http::{header, Method, StatusCode},
routing::{get, Router},
};
use axum_csrf_sync_pattern::{CsrfSynchronizerTokenLayer, RegenerateToken};
use axum_sessions::SessionLayer;
use rand::RngCore;
use tower_http::cors::{AllowOrigin, CorsLayer};

let mut secret = [0; 64];
rand::thread_rng().try_fill_bytes(&mut secret).unwrap();

async fn handler() -> axum::http::StatusCode {
axum::http::StatusCode::OK
async fn handler() -> StatusCode {
StatusCode::OK
}

let app = axum::Router::new()
.route("/", axum::routing::get(handler).post(handler))
let app = Router::new()
.route("/", get(handler).post(handler))
.layer(
// See example above for custom layer configuration.
axum_csrf_sync_pattern::CsrfSynchronizerTokenLayer::default()
)
.layer(
axum_sessions::SessionLayer::new(
async_session::MemoryStore::new(),
&secret
)
CsrfSynchronizerTokenLayer::default()
)
.layer(SessionLayer::new(MemoryStore::new(), &secret))
.layer(
tower_http::cors::CorsLayer::new()
.allow_origin(tower_http::cors::AllowOrigin::list(["https://www.example.com".parse().unwrap()]))
.allow_methods([axum::http::Method::GET, axum::http::Method::POST])
.allow_headers([axum::http::header::CONTENT_TYPE, "X-CSRF-TOKEN".parse().unwrap()])
CorsLayer::new()
.allow_origin(AllowOrigin::list(["https://www.example.com".parse().unwrap()]))
.allow_methods([Method::GET, Method::POST])
.allow_headers([header::CONTENT_TYPE, "X-CSRF-TOKEN".parse().unwrap()])
.allow_credentials(true)
.expose_headers(["X-CSRF-TOKEN".parse().unwrap()]),
);
Expand Down
2 changes: 1 addition & 1 deletion examples/cross-site/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "cross-site"
authors = ["LeoniePhiline <awoo@posteo.de>"]
version = "0.1.0"
version = "0.1.1"
edition = "2021"
publish = false

Expand Down
33 changes: 19 additions & 14 deletions examples/cross-site/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
use std::net::SocketAddr;

use async_session::MemoryStore;
use axum::{
http::{header, Method, StatusCode},
response::IntoResponse,
routing::{get, Router},
Server,
};
use axum_csrf_sync_pattern::CsrfSynchronizerTokenLayer;
use axum_sessions::SessionLayer;
use color_eyre::eyre::{self, eyre, WrapErr};
use rand::RngCore;
use tower_http::cors::{AllowOrigin, CorsLayer};

#[tokio::main]
async fn main() -> eyre::Result<()> {
Expand All @@ -17,7 +25,7 @@ async fn main() -> eyre::Result<()> {
.wrap_err("Failed to initialize tracing-subscriber.")?;

let frontend = async {
let app = axum::Router::new().route("/", axum::routing::get(index));
let app = Router::new().route("/", get(index));

// Visit "http://127.0.0.1:3000/" in your browser.
serve(app, 3000).await;
Expand All @@ -27,24 +35,21 @@ async fn main() -> eyre::Result<()> {
let mut secret = [0; 64];
rand::thread_rng().try_fill_bytes(&mut secret).unwrap();

let app = axum::Router::new()
.route("/", axum::routing::get(get_token).post(post_handler))
.layer(axum_csrf_sync_pattern::CsrfSynchronizerTokenLayer::default())
.layer(axum_sessions::SessionLayer::new(
async_session::MemoryStore::new(),
&secret,
))
let app = Router::new()
.route("/", get(get_token).post(post_handler))
.layer(CsrfSynchronizerTokenLayer::default())
.layer(SessionLayer::new(MemoryStore::new(), &secret))
.layer(
tower_http::cors::CorsLayer::new()
.allow_origin(tower_http::cors::AllowOrigin::list([
CorsLayer::new()
.allow_origin(AllowOrigin::list([
// Allow CORS requests from our frontend.
"http://127.0.0.1:3000".parse().unwrap(),
]))
// Allow GET and POST methods. Adjust to your needs.
.allow_methods([Method::GET, Method::POST])
.allow_headers([
// Allow incoming CORS requests to use the Content-Type header,
axum::http::header::CONTENT_TYPE,
header::CONTENT_TYPE,
// as well as the `CsrfSynchronizerTokenLayer` default request header.
"X-CSRF-TOKEN".parse().unwrap(),
])
Expand All @@ -63,9 +68,9 @@ async fn main() -> eyre::Result<()> {
Ok(())
}

async fn serve(app: axum::Router, port: u16) {
let addr = std::net::SocketAddr::from(([127, 0, 0, 1], port));
axum::Server::bind(&addr)
async fn serve(app: Router, port: u16) {
let addr = SocketAddr::from(([127, 0, 0, 1], port));
Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
Expand Down
2 changes: 1 addition & 1 deletion examples/same-site/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "same-site"
authors = ["LeoniePhiline <awoo@posteo.de>"]
version = "0.1.0"
version = "0.1.1"
edition = "2021"
publish = false

Expand Down
18 changes: 10 additions & 8 deletions examples/same-site/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
use async_session::MemoryStore;
use axum::{
http::{header, StatusCode},
response::IntoResponse,
routing::get,
Server,
};
use axum_csrf_sync_pattern::CsrfSynchronizerTokenLayer;
use axum_sessions::SessionLayer;
use color_eyre::eyre::{self, eyre, WrapErr};
use rand::RngCore;

Expand All @@ -20,15 +25,12 @@ async fn main() -> eyre::Result<()> {
rand::thread_rng().try_fill_bytes(&mut secret).unwrap();

let app = axum::Router::new()
.route("/", axum::routing::get(index).post(handler))
.layer(axum_csrf_sync_pattern::CsrfSynchronizerTokenLayer::default())
.layer(axum_sessions::SessionLayer::new(
async_session::MemoryStore::new(),
&secret,
));
.route("/", get(index).post(handler))
.layer(CsrfSynchronizerTokenLayer::default())
.layer(SessionLayer::new(MemoryStore::new(), &secret));

// Visit "http://127.0.0.1:3000/" in your browser.
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
Server::bind(&"0.0.0.0:3000".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
Expand All @@ -44,6 +46,6 @@ async fn index() -> impl IntoResponse {
)
}

async fn handler() -> axum::http::StatusCode {
async fn handler() -> StatusCode {
StatusCode::ACCEPTED
}
71 changes: 39 additions & 32 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,37 +78,40 @@
//! Configure your session and CSRF protection layer in your backend application:
//!
//! ```rust
//! use async_session::MemoryStore;
//! use axum::{
//! body::Body,
//! http::StatusCode,
//! routing::{get, Router},
//! };
//! use axum_csrf_sync_pattern::{CsrfSynchronizerTokenLayer, RegenerateToken};
//! use axum_sessions::SessionLayer;
//! use rand::RngCore;
//!
//! let mut secret = [0; 64];
//! rand::thread_rng().try_fill_bytes(&mut secret).unwrap();
//!
//! async fn handler() -> axum::http::StatusCode {
//! axum::http::StatusCode::OK
//! async fn handler() -> StatusCode {
//! StatusCode::OK
//! }
//!
//! let app = axum::Router::new()
//! .route("/", axum::routing::get(handler).post(handler))
//! let app = Router::new()
//! .route("/", get(handler).post(handler))
//! .layer(
//! axum_csrf_sync_pattern::CsrfSynchronizerTokenLayer::default()
//! CsrfSynchronizerTokenLayer::default()
//!
//! // Optionally, configure the layer with the following options:
//!
//! // Default: RegenerateToken::PerSession
//! .regenerate(axum_csrf_sync_pattern::RegenerateToken::PerUse)
//! .regenerate(RegenerateToken::PerUse)
//! // Default: "X-CSRF-TOKEN"
//! .request_header("X-Custom-CSRF-Token-Client-Request-Header")
//! .request_header("X-Custom-Request-Header")
//! // Default: "X-CSRF-TOKEN"
//! .response_header("X-Custom-CSRF-Token-Server-Response-Header")
//! .response_header("X-Custom-Response-Header")
//! // Default: "_csrf_token"
//! .session_key("_custom_csrf_token_session_key")
//! .session_key("_custom_session_key")
//! )
//! .layer(
//! axum_sessions::SessionLayer::new(
//! async_session::MemoryStore::new(),
//! &secret
//! )
//! );
//! .layer(SessionLayer::new(MemoryStore::new(), &secret));
//!
//! // Use hyper to run `app` as service and expose on a local port or socket.
//!
Expand All @@ -125,15 +128,15 @@
//! ```javascript
//! const test = async () => {
//! // Receive CSRF token (Default response header name: 'X-CSRF-TOKEN')
//! const token = (await fetch('/')).headers.get('X-Custom-CSRF-Token-Server-Response-Header');
//! const token = (await fetch('/')).headers.get('X-Custom-Response-Header');
//!
//! // Submit data using the token
//! await fetch('/', {
//! method: 'POST',
//! headers: {
//! 'Content-Type': 'application/json',
//! // Default request header name: 'X-CSRF-TOKEN'
//! 'X-Custom-CSRF-Token-Client-Request-Header': token,
//! 'X-Custom-Request-Header': token,
//! },
//! body: JSON.stringify({ /* ... */ }),
//! });
Expand All @@ -147,32 +150,36 @@
//! Configure your CORS layer, session and CSRF protection layer in your backend application:
//!
//! ```rust
//! use async_session::MemoryStore;
//! use axum::{
//! body::Body,
//! http::{header, Method, StatusCode},
//! routing::{get, Router},
//! };
//! use axum_csrf_sync_pattern::{CsrfSynchronizerTokenLayer, RegenerateToken};
//! use axum_sessions::SessionLayer;
//! use rand::RngCore;
//! use tower_http::cors::{AllowOrigin, CorsLayer};
//!
//! let mut secret = [0; 64];
//! rand::thread_rng().try_fill_bytes(&mut secret).unwrap();
//!
//! async fn handler() -> axum::http::StatusCode {
//! axum::http::StatusCode::OK
//! async fn handler() -> StatusCode {
//! StatusCode::OK
//! }
//!
//! let app = axum::Router::new()
//! .route("/", axum::routing::get(handler).post(handler))
//! let app = Router::new()
//! .route("/", get(handler).post(handler))
//! .layer(
//! // See example above for custom layer configuration.
//! axum_csrf_sync_pattern::CsrfSynchronizerTokenLayer::default()
//! )
//! .layer(
//! axum_sessions::SessionLayer::new(
//! async_session::MemoryStore::new(),
//! &secret
//! )
//! CsrfSynchronizerTokenLayer::default()
//! )
//! .layer(SessionLayer::new(MemoryStore::new(), &secret))
//! .layer(
//! tower_http::cors::CorsLayer::new()
//! .allow_origin(tower_http::cors::AllowOrigin::list(["https://www.example.com".parse().unwrap()]))
//! .allow_methods([axum::http::Method::GET, axum::http::Method::POST])
//! .allow_headers([axum::http::header::CONTENT_TYPE, "X-CSRF-TOKEN".parse().unwrap()])
//! CorsLayer::new()
//! .allow_origin(AllowOrigin::list(["https://www.example.com".parse().unwrap()]))
//! .allow_methods([Method::GET, Method::POST])
//! .allow_headers([header::CONTENT_TYPE, "X-CSRF-TOKEN".parse().unwrap()])
//! .allow_credentials(true)
//! .expose_headers(["X-CSRF-TOKEN".parse().unwrap()]),
//! );
Expand Down

0 comments on commit bd97c0d

Please sign in to comment.