0

我也想为 HTTPS 流量打开后端 NodeJS 应用程序。我使用以下命令在 backend/secrets 应用程序中创建了 key.pem 和 cert.pem 文件(自行分配):

$ openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem

然后更改main.ts文件如下:

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { ConfigService } from './modules/config/config.service';
import { ValidationPipe } from '@nestjs/common';
import { AppModule } from './modules/app/app.module';
import { AppLogger } from './modules/app/app.logger';
import { ExpressAdapter } from '@nestjs/platform-express';
import * as cors from 'cors';
import { TransformInterceptor } from './modules/common/interceptors/TransformInterceptor';
import * as express from 'express';
import { ErrorFilter } from './modules/errors/error.filter';
import * as https from 'https'; //ES 6
import fs from 'fs';
async function bootstrap() {
  const logger = new AppLogger();
  logger.info(`NodeJs Version ${process.version}`);
  logger.info(JSON.stringify(process.env));
  const server = express();
  const app = await NestFactory.create(AppModule, new ExpressAdapter(server), {
    logger,
  });
  app.useGlobalPipes(new ValidationPipe({ transform: true, whitelist: true }));
  const apiVersionPrefix: string = process.env.API_VERSION || 'api';
  app.setGlobalPrefix(apiVersionPrefix);
  app.useGlobalInterceptors(new TransformInterceptor());
  const options = new DocumentBuilder()
    .setTitle('Glee2')
    .setDescription('Glee2 API')
    .setVersion('1.0')
    .addTag('customTag')
    .setBasePath(apiVersionPrefix)
    .addBearerAuth() // here is an intentional compile error. Remove the "x" and the backend should compile.
    .build();
  const document = SwaggerModule.createDocument(app, options);
  SwaggerModule.setup(`api/${apiVersionPrefix}`, app, document);
  const config: ConfigService = app.get('ConfigService');
  const whitelist = config.CORS_WHITELIST;
  const corsOptions = {
    origin(origin, callback) {
      const isOriginAllowed = whitelist.indexOf(origin) !== -1;
      const allowAccessAnyway = whitelist.length === 0;
      if (isOriginAllowed || allowAccessAnyway) {
        callback(null, true);
      } else {
        callback(new Error('Not allowed by CORS'));
      }
    },
  };
  const httpsOptions = {
    key: fs.readFileSync('./secrets/key.pem'),
    cert: fs.readFileSync('./secrets/cert.pem'),
  };
  app.use(cors(corsOptions));
  app.useGlobalFilters(new ErrorFilter());
  await app.listen(config.PORT);
  await https.createServer(httpsOptions, server).listen(443);
  logger.log(`Listening on port ${config.PORT}.`);
}
bootstrap();

在 AWS EC2 实例中,打开 443 的端口。HTTP 的 3030 端口运行良好并返回响应:

$ curl -s http://34.201.57.229:3030/api/status

但是,使用 HTTPS 的查询不起作用并且不返回任何内容。

$ curl -s https://34.201.57.229:443/api/status

$ curl -v https://34.201.57.229:443/api/status

*   Trying 34.201.57.229...
* TCP_NODELAY set
* Connection failed
* connect to 34.201.57.229 port 443 failed: Connection refused
* Failed to connect to 34.201.57.229 port 443: Connection refused
* Closing connection 0
curl: (7) Failed to connect to 34.201.57.229 port 443: Connection refused

问题是端口 443 对所有流量开放

在此处输入图像描述

如何使后端使用 HTTPS?

4

1 回答 1

1

你可以试试下面的代码:

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { ConfigService } from './modules/config/config.service';
import { ValidationPipe } from '@nestjs/common';
import { AppModule } from './modules/app/app.module';
import { AppLogger } from './modules/app/app.logger';
import { ExpressAdapter } from '@nestjs/platform-express';
import * as cors from 'cors';
import { TransformInterceptor } from './modules/common/interceptors/TransformInterceptor';
import * as express from 'express';
import { ErrorFilter } from './modules/errors/error.filter';
import * as https from 'https'; //ES 6
// modified here
import * as http from 'http'; //ES 6
import fs from 'fs';
async function bootstrap() {
  const logger = new AppLogger();
  logger.info(`NodeJs Version ${process.version}`);
  logger.info(JSON.stringify(process.env));
  const app = await NestFactory.create(AppModule, new ExpressAdapter(server), {
    logger,
  });
  app.useGlobalPipes(new ValidationPipe({ transform: true, whitelist: true }));
  const apiVersionPrefix: string = process.env.API_VERSION || 'api';
  app.setGlobalPrefix(apiVersionPrefix);
  app.useGlobalInterceptors(new TransformInterceptor());
  const options = new DocumentBuilder()
    .setTitle('Glee2')
    .setDescription('Glee2 API')
    .setVersion('1.0')
    .addTag('customTag')
    .setBasePath(apiVersionPrefix)
    .addBearerAuth() // here is an intentional compile error. Remove the "x" and the backend should compile.
    .build();
  const document = SwaggerModule.createDocument(app, options);
  SwaggerModule.setup(`api/${apiVersionPrefix}`, app, document);
  const config: ConfigService = app.get('ConfigService');
  const whitelist = config.CORS_WHITELIST;
  const corsOptions = {
    origin(origin, callback) {
      const isOriginAllowed = whitelist.indexOf(origin) !== -1;
      const allowAccessAnyway = whitelist.length === 0;
      if (isOriginAllowed || allowAccessAnyway) {
        callback(null, true);
      } else {
        callback(new Error('Not allowed by CORS'));
      }
    },
  };
  const httpsOptions = {
    key: fs.readFileSync('./secrets/key.pem'),
    cert: fs.readFileSync('./secrets/cert.pem'),
  };
  app.use(cors(corsOptions));
  app.useGlobalFilters(new ErrorFilter());

  // modified here
  const httpServer = http.createServer(app);
  const httpsServer = https.createServer(httpsOptions, app);

  httpServer.listen(config.PORT);
  httpsServer.listen(443);
  // modified end

  logger.log(`Listening on port ${config.PORT}.`);
}
bootstrap();

于 2021-10-10T09:08:23.277 回答