auth0 / express-jwt

connect/express middleware that validates a JsonWebToken (JWT) and set the req.user with the attributes

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Typescript error when using ExpressJwtRequest

strmer15 opened this issue · comments

Description

Using the ExpressJwtRequest with Express causes this error to be thrown by the Typescript compiler, when "strict": true is set:

No overload matches this call.
  The last overload gave the following error.
    Argument of type '(req: ExpressJwtRequest<jwt.JwtPayload>, res: Response<any, Record<string, any>>) => Response<any, Record<string, any>> | undefined' is not assignable to parameter of type 'RequestHandlerParams<ParamsDictionary, any, any, ParsedQs, Record<string, any>>'.
      Type '(req: ExpressJwtRequest<jwt.JwtPayload>, res: Response<any, Record<string, any>>) => Response<any, Record<string, any>> | undefined' is not assignable to type 'RequestHandler<ParamsDictionary, any, any, ParsedQs, Record<string, any>>'.
        Types of parameters 'req' and 'req' are incompatible.
          Type 'Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>' is not assignable to type 'ExpressJwtRequest<jwt.JwtPayload>'.
            Property 'auth' is missing in type 'Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>' but required in type '{ auth: jwt.JwtPayload; }'.ts(2769)

Reproduction

Use the Typescript example found on the main page with "strict": true in your tsconfig.json:

import { expressjwt, ExpressJwtRequest } from "express-jwt";

app.get(
  "/protected",
  expressjwt({ secret: "shhhhhhared-secret", algorithms: ["HS256"] }),
  function (req: ExpressJwtRequest, res: express.Response) {
    if (!req.auth.admin) return res.sendStatus(401);
    res.sendStatus(200);
  }
);

Environment

  • Version of this library used: express-jwt 7.5.2
  • Version of the platform or framework used, if applicable: express 4.18.0, @types/express 4.17.13
  • Other relevant versions (language, server software, OS, browser): typescript 4.6.3, node 12.22.12
  • Other modules/plugins/libraries that might be involved: jwks-rsa 2.1.0

Workaround is to use ExpressJwtRequestUnrequired instead.

Yes, I was able to reproduce this problem and I can't see an easy way to fix it.

I'd like to keep auth as required because that's the reality if experssJwt happens before the handler.

But OTOH, all examples I see extending express request add the properties as optional.

If we decide to change that, I will need to release a new major because making it optional will break existing projects using v7.

And tbh I don't like the name ExpressJwtRequestUnrequired.. Another option could be to exporte a new Request only (equals to the Unrequired one)

Hey, a related issue in the node-jwks-rsa repo is being tracked as well: auth0/node-jwks-rsa#299

It is my understanding this issue lies entirely in auth0/node-jwks-rsa#299 from them using deprecated types.

I've submitted auth0/node-jwks-rsa#301, which fixes my issues.

You may want to check if the proposed index.d.ts solves your issues as well.

@carboneater thanks for the fix in node-jwks-rsa! Your solution is much better.

I recently added an alias to express-jwt for the old signatures because it was reported in another thread:
https://github.com/auth0/express-jwt/blob/master/src/index.ts#L8-L11

Anyway that should be fixed now in both places 🎉

I just deprecated the ExpressJwtRequest type and added a new one called just Request with optional auth. We should use that one always, as follows:

import { expressjwt, Request } from "express-jwt";

app.get(
  "/protected",
  expressjwt({ secret: "shhhhhhared-secret", algorithms: ["HS256"] }),
  function (req: Request, res: express.Response) {
    if (!req.auth?.admin) return res.sendStatus(401);
    res.sendStatus(200);
  }
);