-
Prevent user enumeration.
All routes should be protected against user enumeration.
-
Always confirm any change to security settings using two-factor method if available.
-
Prevent phishing attacks.
You can play around with the API by using the provided example and using Swagger:
# Clone the project
git clone https://github.com/insertish/rauth
cd rauth
# Bring up MongoDB
docker-compose up -d database
# Start the example
cargo run --example rocket_mongodb --features example
Now you can navigate to http://localhost:8000/swagger!
Getting started is very simple, first add rAuth to your Cargo.toml
:
[dependencies]
rauth = { git = "https://github.com/insertish/rauth", features = [ "rocket_impl", "okapi_impl", "async-std-runtime", "database-mongodb" ] }
rocket_rauth = { git = "https://github.com/insertish/rauth" }
# For the example below, you also need:
rocket = { version = "0.5.0-rc.2", default-features = false, features = ["json"] }
mongodb = { version = "2.2.1", default-features = false, features = ["async-std-runtime"] }
Then you can create a new instance of rAuth and mount it on to Rocket.
#[macro_use]
extern crate rocket;
use mongodb::{options::ClientOptions, Client};
use rauth::database::MongoDb;
use rauth::Migration;
#[launch]
async fn rocket() -> _ {
// Prepare MongoDB configuration
let client_options = ClientOptions::parse("mongodb://localhost:27017")
.await
.expect("Valid connection URL");
// Connect to MongoDB
let client = Client::with_options(client_options).expect("MongoDB server");
// Prepare rAuth database abstraction
let database = rauth::Database::MongoDb(MongoDb(client.database("rauth")));
// Run database migrations
// TODO: you should only run this once and have this as part of your migrations
// Also keep this up to date with the "migrations" section down below this one.
database.run_migration(Migration::M2022_06_03EnsureUpToSpec).await.unwrap();
// Configure rAuth however you need to
let rauth = rauth::RAuth {
database,
..Default::default()
};
// Build your web server as usual...
rocket::build()
// Attach the configuration as state
.manage(rauth)
// Mount authentication routes
.mount("/auth/account", rocket_rauth::routes::account::routes().0)
.mount("/auth/session", rocket_rauth::routes::session::routes().0)
.mount("/auth/mfa", rocket_rauth::routes::mfa::routes().0)
}
To test the library, pull up required services:
# Start MongoDB and Sendria
docker-compose up -d
Then you can run the tests:
# Run cargo test
cargo test --features test
# Or using nextest
cargo nextest run --features test
Run a coverage test:
# Run tarpaulin
cargo tarpaulin --features test --out html
Migrating the database is easy, you just have to orchestrate it yourself, ideally you have your own versioned migration system which you can slot changes into.
use rauth::{ Database, Migration };
// Acquire the database first
let database = Database::[..];
// Then run a specific migration
database.run_migration(Migration::[..]).await.unwrap();
The following migrations are available and must be run in order:
Date | Migration | Description |
---|---|---|
2022-06-03 | M2022_06_03EnsureUpToSpec |
Reset and reconstruct indexes to be fully up to date. This will also create any missing collections. |
rAuth uses email / password combinations to authenticate users and nothing else, this might not be what you're looking for but I personally prefer this format.
- If you need usernames, you need to handle this on your end.
When a user signs in, a new session is created, every single device a user logs in on has a unique session.
- This means a user can then log themselves out of old sessions or otherwise see where they are logged in.
Internally rAuth stores emails with and without special characters, +.
.
- This means we can support plus signing without allowing the same email to sign up multiple times.
- For example,
inbox+a@example.com
andinbox+b@example.com
are treated as equal. - But since we are still storing the original email, we still send them marked with the user's sign.
- For example,
- In the case of Gmail, all emails with dots are forwarded to those without them, this can lead to some unfortunate situations.
- Generally, we treat all emails with dots as their non-dot counterpart when checking if an email exists.
- This may inconvenience some users but I would rather avoid situations like above or duplicate accounts.
- When logging in, we use the normalised email to find the correct account.