Skip to content

Stateless session backed by authentication against mongodb collection

License

Notifications You must be signed in to change notification settings

uscreen/fastify-mongo-auth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

fastify-mongo-auth

Test CI Test Coverage Known Vulnerabilities NPM Version

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

Install

$ yarn add @uscreen.de/fastify-mongo-auth

Add Dependencies

$ 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

Example

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
  )
}

Options

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 }). {}

API

get collection()

Returns the fastify-mongo-crud collection object where the accounts are stored.

authorized(req, res, next)

PreHandler validating authentication. Throws an 401 Unauthorized error on unvalid authentication.

createHash(password)

Creates a hash from given password. Useful when creating a new account or changing an account's password.

verifyHash(password, hash)

Verifies the given password to the given hash.

async loginHandler(req)

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"
}

async logoutHandler(req)

Handler for logging off from an account (i.e. called by POST /logout). Expects a req object without a body.

async currentUserHandler(req)

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.


Roadmap

  • docs
  • improved dependency handling
  • improved onboarding
  • maybe add more handler (register, reset, etc.)?
  • maybe add routes?

Changelog

v1.1.0

Added

  • filter option to filter valid accounts (defaults to {})

v1.0.0

Changed

v0.2.0

Added

  • cookie options (see cookie defaults to { path: '/' }

v0.1.0

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)

v0.0.0

  • init

License

Licensed under MIT.

Published, Supported and Sponsored by u|screen

About

Stateless session backed by authentication against mongodb collection

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •