JWT Authentication
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