Stateless session backed by authentication against mongodb collection
Provides:
fastify.auth
- the authentication adapter with it's api (see below)req.session
- as provided by @fastify/secure-sessionreq.user
- (default, customize bydecorateRequest
option) will be a current authenticated user account
Uses secure-password for hashing and verification
$ yarn add @uscreen.de/fastify-mongo-auth
$ yarn add @fastify/mongodb @uscreen.de/fastify-mongo-crud
The session package @fastify/secure-session
(see @npm) requires a secret or key. We stick to recommended setup with a generated key below, so you should generate one too:
$ secure-session-gen-key > session-key
Setup within a plugins/mongo.js
file to resolve required dependencies before:
import fs from 'fs'
import path from 'path'
import fp from 'fastify-plugin'
import mongodb from '@fastify/mongodb'
import crud from '@uscreen.de/fastify-mongo-crud'
import auth from '@uscreen.de/fastify-mongo-auth'
/**
* mongodb related
*/
export default fp(async (fastify, opts) => {
/**
* 1) setup mongodb connection
*/
await fastify.register(mongodb, {
url: opts.mongoUri
})
/**
* 2) setup CRUD factory
*/
await fastify.register(crud)
/**
* 3) enable authentication
*/
await fastify.register(auth, {
key: fs.readFileSync(path.join(fastify.root, 'session-key')),
decorateRequest: 'account'
})
})
Prepare account within a service/accounts.js
file:
export default async fastify => {
const { auth } = fastify
/**
* registration
* -> body.{username, password}
* <- account.{username, _id}
*/
fastify.post('/register', async req => ({
account: await auth.collection.create({
hash: auth.createHash(req.body.password),
username: req.body.username.toLowerCase()
})
}))
}
Usage within a services/auth.js
file:
export default async fastify => {
const { auth } = fastify
/**
* authentication / login
* -> body.{username, password}
* <- account.{username, _id}
*/
fastify.post('/login', auth.loginHandler)
/**
* authentication / logout
* -> {} - no payload required
* <- {} - no payload returned
*/
fastify.post('/logout', auth.logoutHandler)
/**
* authentication / check currentUser
* <- account.{username, _id}
*/
fastify.get(
'/currentUser',
{
preHandler: auth.authorized
},
auth.currentUserHandler
)
}
Option | Description | Default |
---|---|---|
collection | Name of the mongodb collection the accounts are stored in. | "accounts" |
cookie | Options for session cookie as listed here cookie . |
{ path: '/' } |
key | Path to file of session-key @fastify/secure-session uses to ensure secure stateless cookie sessions. |
"" |
decorateRequest | Property providing current authenticated account object within request object. (ie.: req.user as default) |
"user" |
usernameToLowerCase | Should usernames be treated case-insensitive (by lower-casing all queries) or not. | true |
usernameField | Name of property for usernames. Affects mongodb documents and the login handler (see below). | "username" |
passwordField | Name of property for passwords. | "password" |
filter | Filter expression for valid accounts (e.g. { active: true } ). |
{} |
Returns the fastify-mongo-crud
collection object where the accounts are stored.
PreHandler validating authentication. Throws an 401 Unauthorized
error on unvalid authentication.
Creates a hash from given password. Useful when creating a new account or changing an account's password.
Verifies the given password to the given hash.
Handler for logging in to an account (i.e. called by POST /login
). Expects a req
object with a body
containing credentials as configured in Options, defaults to:
{
"username": "a user's name",
"password": "a user's password"
}
Handler for logging off from an account (i.e. called by POST /logout
). Expects a req
object without a body
.
Handler returning the current authenticated account (i.e. called by GET /currentUser
) or an empty object if no account is authenticated. Expects a req
object without a body
.
- docs
- improved dependency handling
- improved onboarding
- maybe add more handler (register, reset, etc.)?
- maybe add routes?
- filter option to filter valid accounts (defaults to
{}
)
- switch to ESM only
- upgrade to [email protected]
- cookie options (see
cookie
defaults to{ path: '/' }
- uses lower case usernames by default
- preHandler stops logging empty session as error
- new option
usernameToLowerCase
to disable case-insensitive usernames (defaults to true)
- init
Licensed under MIT.
Published, Supported and Sponsored by u|screen