将 Helmet 升级到 v4.5.0 并需要与 IHelmetContentSecurityPolicyDirectives 等效的类型

问题描述

只是修改了 NodeJS/Typescript 应用程序中使用的依赖项,并且在将 Helmet 从版本“3.23.2”更改为“4.5.0”时遇到了障碍。

我已经从 package.json 文件删除了依赖项 "@types/helmet": "0.0.47"。

编译会导致以下语义错误

src/loaders/security.ts(2,18): error TS2305: Module '"helmet"' has no exported member 'IHelmetContentSecurityPolicyDirectives'.
src/options.ts(1,10): error TS2305: Module '"helmet"' has no exported member 'IHelmetContentSecurityPolicyDirectives'.

options.ts 包括

import { IHelmetContentSecurityPolicyDirectives } from 'helmet';

export interface Options {
  redirectUrl: string;
  mountPath: string;
  serviceName?: string;
  views?: string | string[];
  csp?: IHelmetContentSecurityPolicyDirectives;
  i18n?: I18noptions;
}

security.ts 定义为:

import { Application } from 'express';
import helmet,{ IHelmetContentSecurityPolicyDirectives } from 'helmet';
import logger from '../lib/logger';

const configureSecurity = (app: Application,csp: IHelmetContentSecurityPolicyDirectives | undefined): void => {
  logger.info('Configuring Security using Helmet');
  const defaultSrc = (csp && csp.defaultSrc) || [];
  const styleSrc = (csp && csp.styleSrc) || [];
  const scriptSrc = (csp && csp.scriptSrc) || [];
  app.use(helmet({
    contentSecurityPolicy: {
      directives: {
        defaultSrc: [...defaultSrc,"'self'"],styleSrc: [...styleSrc,scriptSrc: [
          ...scriptSrc,"'self'","'sha256-+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'",],},}));
};

export default configureSecurity;

我不知道用什么代替 IHelmetContentSecurityPolicyDirectives 作为 csp 类型。

解决方法

这里是头盔的维护者。

Helmet v3 没有正式的 TypeScript 定义,而 Helmet v4 有。简而言之,您看到这个问题是因为 Helmet v3 的社区制作类型没有完全映射到 Helmet v4 中的官方类型。

您正在寻找 IHelmetContentSecurityPolicyDirectives 的替代品。以下是 Helmet 的内容安全策略模块的官方类型定义中的 a snippet

export interface ContentSecurityPolicyOptions {
  directives?: Record<
    string,| Iterable<ContentSecurityPolicyDirectiveValue>
    | typeof dangerouslyDisableDefaultSrc
  >;
  reportOnly?: boolean;
}

directives的{​​{1}}键是旧ContentSecurityPolicyOptions的“轮回”。

我看到两个选项:

  1. 自己定义类型,然后使用。例如:

    IHelmetContentSecurityPolicyDirectives

    然后您可以使用 type CspDirectiveValue = | string | ((req: IncomingMessage,res: ServerResponse) => string); type CspDirectives = Record<string,Iterable<CspDirectiveValue>>; 代替旧的 CspDirectives 类型。

  2. 稍微修改一下代码。

    您可以更新 IHelmetContentSecurityPolicyDirectives 界面以获取所有 Helmet 的选项:

    Options

    然后您可以在 import helmet from 'helmet'; export interface Options { // ... helmetOptions: Parameters<typeof helmet>[0]; // ... } 中使用它:

    configureSecurity

    您的实际代码可能会有所不同。