koajs / jwt

Koa middleware for validating JSON Web Tokens
MIT License
1.34k stars 120 forks source link

Does not work if used multiple times #177

Closed JonathanWilbur closed 2 years ago

JonathanWilbur commented 3 years ago

First off, I am aware that the README documentation includes instructions on how to exempt certain paths from JWT authentication. I knowingly deviated from these, but in doing so, I found what I believe is unintuitive and dangerous behavior from this library.

I simply create two arrays, one for routes that need authentication, and one for routes that do not:

const preAuthServiceRouters: Router[] = [
    routeAuthenticationInstructions,
    routePostAuthentication,
];

const serviceRouters: Router[] = [
    routeSetup,
    routeGetAuthentication,
];

Then, further on down, I use each router's routes in the v1 route (these will be namespaced under /api/v1, which is why I do this). As you can see below, I only apply authentication middleware to authenticated routes.

    preAuthServiceRouters.forEach((sr) => {
        v1Router.use(sr.routes());
    });
    serviceRouters.forEach((sr) => {
        sr.use(jwtMiddleware);
        v1Router.use(sr.routes());
    });

The authentication middleware is defined as:

    const jwtMiddleware = koaJWT.default({
        secret: koaJwtSecret({
            jwksUri: openid.jwks_uri,
            cache: true,
            cacheMaxEntries: 5,
            cacheMaxAge: 86_400_000,
        }),
        audience: "http://myapi/protected", // I am aware that this is a default setting. I will change it.
        issuer: openid.issuer,
        cookie: "auth-cookie",
    });

The bug is that, when I selectively apply authentication this way, the authentication middleware seems to only apply to the last route in the array of protected routes. In the case of the example above, routeGetAuthentication would be protected, but routeSetup would not be protected. If you switch their order, the opposite will be true.

sdd commented 3 years ago

I don't think this is a bug in koa-jwt. It looks like a consequence of how you have configured your routes. koa-jwt will act as an authentication gate against any middleware that comes downstream of it.