Stateless session backed by authentication against mongodb collection




> 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-session
- req.user - (default, customize by decorateRequest option) will be a current authenticated user account
Uses secure-password for hashing and verification
``sh`
$ pnpm add @uscreen.de/fastify-mongo-auth
`sh`
$ pnpm 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:
`sh`
$ secure-session-gen-key > session-key
__Setup__ within a plugins/mongo.js file to resolve required dependencies before:
`js
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:
`js
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:
`js
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
| __cookie__ | Options for session cookie as listed here . | { path: '/' } |@fastify/secure-session
| __key__ | Path to file of session-key uses to ensure secure stateless cookie sessions. | "" |req.user
| __decorateRequest__ | Property providing current authenticated account object within request object. (ie.: as default) | "user" |true
| __usernameToLowerCase__ | Should usernames be treated case-insensitive (by lower-casing all queries) or not. | |"username"
| __usernameField__ | Name of property for usernames. Affects mongodb documents and the login handler (see below). | |"password"
| __passwordField__ | Name of property for passwords. | |{ active: true }
| __filter__ | Filter expression for valid accounts (e.g. ). | {} |
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:
`json`
{
"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?
#### Changed
- upgrade to fastify@5.x
#### Added
- filter option to filter valid accounts (defaults to {})
#### Changed
- switch to __ESM only__
- upgrade to fastify@4.x
#### Added
- cookie options (see cookie defaults to { path: '/' }
#### Changed
- uses lower case usernames by default
- preHandler stops logging empty session as error
#### Added
- new option usernameToLowerCase` to disable case-insensitive usernames (defaults to true)
- init
---
Licensed under MIT.
Published, Supported and Sponsored by u|screen