Search code examples
node.jstypescriptexpressjwtexpress-jwt

why the token parameter in verify function is showing error in jwt authentitcation?


I am trying to do jwt authentication and i am getting error like this on verify function.

No overload matches this call. Overload 1 of 3, '(token: string, secretOrPublicKey: Secret, options?: VerifyOptions | undefined): string | object', gave the following error. Argument of type 'string | string[] | undefined' is not assignable to parameter of type 'string'. Type 'undefined' is not assignable to type 'string'. Overload 2 of 3, '(token: string, secretOrPublicKey: Secret | GetPublicKeyOrSecret, callback?: VerifyCallback | undefined): void', gave the following error.

import { NextFunction, Request, Response } from "express";
import jwt from "jsonwebtoken";
import config from "../config/default"

var authorization = function (req:Request, res:Response, next:NextFunction) {
    var token = req.headers['x-access-token'];
    var msg = {auth: false, message: 'No token provided.'};

    if (!token) res.status(500).send(msg);

    jwt.verify(token, config.token.secret, function (err) {
        var msg = {auth: false, message: 'Failed to authenticate token.'};
        if (err) res.status(500).send(msg);
        next();
    });
}

module.exports = authorization;


Solution

  • The problem is req.headers returns value of type string | string[] | undefined. And you're trying to pass it as an argument to the function expecting type string in that position. Thus the error.

    There are some issues with your code you have to address to fix it:

    • after if (!token) res.status(500).send(msg) function execution does not stop. It will proceed to the jwt.verify. Though it won't pass token check with falsy token it will run the verify function anyway. This condition does not narrow the type.
    declare const n: number | null
    
    if (!n) {
      console.log('0, NaN or null')
    } else {
      type N = typeof n // N ~ number
    }
    
    if (!n) console.log('0, NaN or null')
    
    type M = typeof n // M ~ number | null
    

    playground link

    • token may be an array of strings

    For your code to typecheck and work correctly you have to narrow the type of token to string:

    import { NextFunction, Request, Response } from "express";
    import jwt, { VerifyErrors } from "jsonwebtoken";
    import config from "../config/default"
    
    var authorization = function (req:Request, res:Response, next:NextFunction) {
        var token = req.headers['x-access-token'];
        var msg = {auth: false, message: 'No token provided.'};
    
        // check whether `token` is an array and get the first element
        // narrows the type to `string | undefined`
        if (Array.isArray(token)) token = token[0];
    
        // narrows the type to `string`
        if (!token) {
          res.status(500).send(msg);
          // return early and prevent execution of the underlying middlewares
          return next(false); 
        }
    
        jwt.verify(token, config.token.secret, function (err: VerifyErrors | null) {
            var msg = {auth: false, message: 'Failed to authenticate token.'};
            if (err) res.status(500).send(msg);
            next();
        });
    }
    
    module.exports = authorization;