Self-hosted Authentication (dbAuth)
Redwood's own dbAuth provides several benefits:
- Use your own database for storing user credentials
- Use your own login, signup and forgot password pages (or use Redwood's pre-built ones)
- Customize login session length
- No external dependencies
- No user data ever leaves your servers
- No additional charges/limits based on number of users
- No third party service outages affecting your site
And potentially one large drawback:
- Use your own database for storing user credentials
However, we're following best practices for storing these credentials:
- Users' passwords are salted and hashed with PBKDF2 before being stored
- Plaintext passwords are never stored anywhere, and only transferred between client and server during the login/signup phase (and hopefully only over HTTPS)
- Our logger scrubs sensitive parameters (like
password
) before they are output - We only store the hashes of reset tokens
Even if you later decide you want to let someone else handle your user data for you, dbAuth is a great option for getting up and running quickly (we even have a generator for creating basic login and signup pages for you).
How It Works
dbAuth relies on good ol' fashioned cookies to determine whether a user is logged in or not. On an attempted login, a serverless function on the api-side checks whether a user exists with the given username (internally, dbAuth refers to this field as username but you can use anything you want, like an email address). If a user with that username is found, does their salted and hashed password match the one in the database?
If so, an HttpOnly, Secure, SameSite cookie (dbAuth calls this the "session cookie") is sent back to the browser containing the ID of the user. The content of the cookie is a simple string, but AES encrypted with a secret key (more on that later).
When the user makes a GraphQL call, we decrypt the cookie and make sure that the user ID contained within still exists in the database. If so, the request is allowed to proceed.
If there are any shenanigans detected (the cookie can't be decrypted properly, or the user ID found in the cookie does not exist in the database) the user is immediately logged out by expiring the session cookie.
Setup
A single CLI command will get you everything you need to get dbAuth working, minus the actual login/signup pages:
yarn rw setup auth dbAuth
You will be prompted to ask if you want to enable WebAuthn support. WebAuthn is an open standard for allowing authentication from devices like TouchID, FaceID, USB fingerprint scanners, and more. If you think you want to use WebAuthn, enter y
at this prompt and read on configuration options.
You can also add WebAuthn to an existing dbAuth install. Read more about WebAuthn usage and config below.
Read the post-install instructions carefully as they contain instructions for adding database fields for the hashed password and salt, as well as how to configure the auth serverless function based on the name of the table that stores your user data. Here they are, but could change in future releases (these do not include the additional WebAuthn required options, make sure you get those from the output of the setup
command):
You will need to add a couple of fields to your User table in order to store a hashed password and salt:
model User {
id Int @id @default(autoincrement())
email String @unique
hashedPassword String // <─┐
salt String // <─┼─ add these lines
resetToken String? // <