@expresso/auth

@expresso's authorization tool

Usage no npm install needed!

<script type="module">
  import expressoAuth from 'https://cdn.skypack.dev/@expresso/auth';
</script>

README

Expresso Auth

Authentication Middleware for Expresso

Summary

Basic Usage

Install:

$ npm i @expresso/auth

Import and use:

import expresso, { IExpressoConfigOptions } from '@expresso/app'
import auth, { IAuthConfig } from '@expresso/auth'
import server from '@expresso/server'

interface IAppConfig extends IAuthConfig, IExpressoConfigOptions {}

const appFactory = expresso((app, config: IAppConfig, environment) => {
  const { jwt, scope, types } = auth.factory(config)

  app.get('/', jwt, types('client'), scopes('namespace:your-scope'), routeHandler)
})

const options = {
  name: 'myApp',
  jwt: {
    algorithms: ['HS256'],
    audience: 'your-audience',
    issuer: 'your-issuer',
    secret: 'shhhhh'
  }
}

server.start(appFactory, options)

URN

Since expresso is an opinionated framework, you must use an URN in the format urn:type:description for the subject private claim in the JWT

Types

The middleware can check if a subject is from a determined type by using the types('type') middleware. It'll parse the URN and check if the types are matching, if not, the user will not be authorized.

Options

The auth middleware takes an option object as configuration. This object is as follows:

export interface IAuthConfig {
  jwt: {
    audience: string
    issuer: string
    algorithms?: string[]
    secret?: string
  },
  jwks?: {
    uri: string
    cache?: boolean
    rateLimit?: boolean
    requestPerMinute?: number
  }
}

The JWT object is required. There's also more than one way to secret your token, this is either with a string secret or a JWKS URI. If the secret is provided, then the JWT string secret will be used. However if you provide the middleware with the jwks key and a uri property then the middleware will request this URI to find the token.

Scopes

This middleware supports scopes. This means you can restrict your token to explicit permission levels using the scopes public claim in your JWT token:

{
  "sub": "yourSubject",
  "name": "John Doe",
  "iat": 1516239022,
  "scope": "namespace:your-scope"
}

The scope can be either a string or an Array. But it'll only validate if your determined scope is equal to the string or if it is included in the array.

You can perform wildcard validation using the * keyword as long as your scope separator is ., for instance, users.* will match all the scopes within the users namespace, but users:* won't.

Conditionals

You can match several scopes using the or and and keywords.

app.get('/', scopes.or(['users.read', 'admin.write']), routeHandler)

Will return true if either the users.read or admin.write is present in the scope public claim.

app.get('/', scopes.and(['users.read', 'admin.write']), routeHandler)

Will return true if both the users.read and admin.write is present in the scope public claim.