Skip to content

Instantly share code, notes, and snippets.

@andywer
Last active August 6, 2020 14:57
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andywer/1571a022fca1d17039b073c3c066f259 to your computer and use it in GitHub Desktop.
Save andywer/1571a022fca1d17039b073c3c066f259 to your computer and use it in GitHub Desktop.
Koa: Passing data from middleware to route handler
/*
* Description:
*
* There are times when we want to re-use some data created/derived in a middleware later in a route handler.
*
* The default Koa way of doing so would be using `context.state`. Unfortunately `context.state` is hard to type and
* quite implicit, since it's an object shared and potentially mutated by all middlewares and the route handler.
*/
/*
* Option 1: Default approach
*/
import createError from "http-errors"
import JWT from "jsonwebtoken"
import Koa from "koa"
import Router from "koa-router"
import logger from "./logger"
import { findProductsByUserId } from "./models/product"
function authenticate() {
return (context: Koa.Context, next: (ctx: Koa.Context) => Promise<any>) => {
try {
const user = JWT.verify(context.request.getHeader("Authorization"), "secret")
// Put user data into context state
context.state.user = user
} catch (error) {
logger.error(error)
throw createError(401)
}
await next(context)
}
}
const app = new Koa()
const router = new Router()
router.get("/products", authenticate(), async ({ response, state }) => {
response.body = await findProductsByUserId(state.user.id)
})
app.use(router.routes())
app.use(router.allowedMethods())
/*
* Option 2: Don't re-use, parse auth token a 2nd time
*
*/
import createError from "http-errors"
import JWT from "jsonwebtoken"
import Koa from "koa"
import Router from "koa-router"
import logger from "./logger"
import { findProductsByUserId } from "./models/product"
function authenticate() {
return (context: Koa.Context, next: (ctx: Koa.Context) => Promise<any>) => {
try {
JWT.verify(context.request.getHeader("Authorization"), "secret")
// Do not even put user data into context state
} catch (error) {
logger.error(error)
throw createError(401)
}
await next(context)
}
}
function getUserFromRequest (request: Koa.Request) {
try {
const user = JWT.verify(request.getHeader("Authorization"), "secret")
return user
} catch (error) {
logger.error(error)
throw createError(401)
}
}
const app = new Koa()
const router = new Router()
router.get("/products", authenticate(), async ({ request, response }) => {
// Parse JWT again
const user = getUserFromRequest(request)
response.body = await findProductsByUserId(user.id)
})
app.use(router.routes())
app.use(router.allowedMethods())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment