为啥验证函数中的令牌参数在 jwt 身份验证中显示错误?

Posted

技术标签:

【中文标题】为啥验证函数中的令牌参数在 jwt 身份验证中显示错误?【英文标题】:why the token parameter in verify function is showing error in jwt authentitcation?为什么验证函数中的令牌参数在 jwt 身份验证中显示错误? 【发布时间】:2021-08-26 02:07:12 【问题描述】:

我正在尝试进行 jwt 身份验证,但在验证功能上遇到了这样的错误。

没有重载匹配这个调用。 重载 1 of 3, '(token: string, secretOrPublicKey: Secret, options?: VerifyOptions | undefined): string |对象',给出以下错误。 'string | 类型的参数字符串[] | undefined' 不能分配给'string' 类型的参数。 类型“未定义”不可分配给类型“字符串”。 Overload 2 of 3, '(token: string, secretOrPublicKey: Secret | GetPublicKeyOrSecret, callback?: VerifyCallback | undefined): void',给出以下错误。

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;

【问题讨论】:

它即将到来是因为您的值 tokensecret 可能未定义。 【参考方案1】:

问题是req.headers 返回string | string[] | undefined 类型的值。您正试图将它作为参数传递给在该位置期望类型 string 的函数。因此错误。

您的代码存在一些问题,您必须解决它才能修复它:

if (!token) res.status(500).send(msg) 函数执行后不会停止。它将转到jwt.verify。虽然它不会通过带有虚假令牌的令牌检查,但无论如何它都会运行验证功能。此条件不会缩小类型。
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 可能是一个字符串数组

为了使您的代码能够进行类型检查并正常工作,您必须将 narrow 的类型 token 转换为 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;

【讨论】:

以上是关于为啥验证函数中的令牌参数在 jwt 身份验证中显示错误?的主要内容,如果未能解决你的问题,请参考以下文章

JWT 为啥我可以绕过身份验证?

如何在 django rest 框架中验证 jwt 身份验证中的令牌

JWT 令牌身份验证失败并显示消息“PII 已隐藏”

根据 JWT 身份验证令牌中的声明验证来自请求的 IP

如何使用 JWT 身份验证获取登录用户信息?

为啥 JWT 是无状态认证?