0.1.0 • Published 5 years ago

jwt-scope v0.1.0

Weekly downloads
1
License
MIT
Repository
github
Last release
5 years ago

jwt-scope

NPM version

Checks if JWT contains required scope(s) to access to an endpoint

Install

$ npm install jwt-scope

Peer dependency: express@^4.0.0

Usage

Use together with express-jwt to validate JWT(JsonWebTokens) and sets req.user

const jwt = require('express-jwt');
const jwtScope = require('jwt-scope');

let options = {};
app.get('/users',
  jwt({ secret: 'shared_secret' }),
  jwtScope('read:users', options),
  function(req, res) { ... });

Allow if any of scope, looks like this:

app.post('/users',
  jwt({ secret: 'shared_secret' }),
  jwtScope('read:users write:users'),
  function(req, res) { ... });

// This user will have access
let user = {
  scope: 'read:users'
};

To require that all scopes are provided, use the requireAll: true option:

app.post('/users',
  jwt({ secret: 'shared_secret' }),
  jwtScope('read:users write:users', { requireAll: true }),
  function(req, res) { ... });

// This user will have access
const authorizedUser = {
  scope: 'read:users write:users'
};

// This user will NOT have access
const unauthorizedUser = {
  scope: 'read:users'
};

Input types

String (space separated)

"write:users read:users"
jwtScope("write:users read:users")

Array

["write:users", "read:users"]
jwtScope(["write:users", "read:users"])

Options

  • scopeKey: The user property name to check for the scope(s).
  • requireAll: true => Requires all scopes to be provided.
    • Default value: false
  • errorToNext: true => Forward errors to express next(), instead of ending the response directly.
    • Default value: false

Examples

Auth0

const express = require('express');
const app = express();
const jwt = require('express-jwt');
const jwksRsa = require('jwks-rsa');
const jwtScope = require('jwt-scope');

// Authentication middleware. When used, the
// Access Token must exist and be verified against
// the Auth0 JSON Web Key Set
const checkJwt = jwt({
  // Dynamically provide a signing key
  // based on the kid in the header and 
  // the signing keys provided by the JWKS endpoint.
  secret: jwksRsa.expressJwtSecret({
    cache: true,
    rateLimit: true,
    jwksRequestsPerMinute: 5,
    jwksUri: `https://YOUR_DOMAIN/.well-known/jwks.json`
  }),

  //  Validate the audience and the issuer.
  audience: 'YOUR_API_IDENTIFIER',
  issuer: `https://YOUR_DOMAIN/`,
  algorithms: ['RS256']
});

/**  Public routes goes here  */
// This route doesn't need authentication
app.get('/api/public', function(req, res) {
  res.json({message: 'Hello from a public endpoint! You don\'t need to be authenticated to see this.'});
});

// This route need authentication
app.get('/api/private', checkJwt, function(req, res) {
  res.json({message: 'Hello from a private endpoint! You need to be authenticated to see this.'});
});

// This route need authentication and scope
app.get('/api/private-scoped', checkJwt, jwtScope('read:messages'), function(req, res) {
  res.json({message: 'Hello from a private endpoint! You need to be authenticated and have a req.user.scope of read:messages to see this.'});
});

/** Private routes goes here  */
app.use(checkJwt);
app.get('/api/another-private-scoped', jwtScope('read:info'), function(req, res) {
  res.json({message: 'Hello from a private endpoint! You need to be authenticated and have `read:info` included in req.user.scope to see this.'});
});

//  Enable Role-Based Access Control for APIs, to add Auth0 permissions in the access token.
//  See https://auth0.com/docs/dashboard/guides/apis/enable-rbac
let options = {
  scopeKey: 'permissions'
};
app.get('/api/another-private-scoped', jwtScope('read:user', options), function(req, res) {
  res.json({message: 'Hello from a private endpoint! You need to be authenticated and have `read:user` included in req.user['permission'] to see this.'});
});

License

This project is licensed under the MIT license. See the LICENSE file for more info.