JWT Authentication

json web tokens

Authentication models for hosting platforms require more considerations due to 3rd party api access. We wanted to be able to issue user auth tokens for 3rd party apps (think OAuth), as well as be able to verify authentication of local native api calls (through our iframe native app hooks). Our solution was to use Json Web Tokens (JWT) with ES256 encryption (public/private key pair), which allows us to verify signed tokens using a public key which can be shared without compromising the security of our tokens. It also allows us to statelessly sign tokens for 3rd party developer use.

Here's a sample implementation of a basic authentication strategy (extensible to allow scoped tokens).

# auth_model.coffee
jwt = require 'jsonwebtoken'

module.exports =
  fromUserId: (userId) ->
    Promise.resolve {
      accessToken: jwt.sign {
          userId: userId
          scopes: ['*']
        }, config.JWT_ES256_PRIVATE_KEY, {
          algorithm: 'ES256'
          issuer: config.JWT_ISSUER
          subject: userId
        }
    }

  userIdFromAccessToken: (token) ->
    Promise.promisify(jwt.verify, jwt)(
      token,
      config.JWT_ES256_PUBLIC_KEY,
      {issuer: config.JWT_ISSUER}
    )
    .then ({userId} = {}) -> userId

And the corresponding Express middleware:

# auth_middleware.coffee
module.exports = (req, res, next) ->
  accessToken = req.query?.accessToken
  unless accessToken?
    return next()

  Auth.userIdFromAccessToken accessToken
  .then User.getById
  .then (user) ->
    if user?
      # Authentication successful
      req.user = user
    next()
  .catch next