I would like to open backend NodeJS app for the HTTPS traffic as well. I created the key.pem and cert.pem file (self assigned) inside the backend/secrets app with the command:
$ openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem
Then changed the main.ts file as below:
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();
In the AWS EC2 instance, open the port for 443. Port 3030 for the HTTP is working well and return the response:
$ curl -s http://34.201.57.229:3030/api/status
However, the query with the HTTPS is not working and doesn't return anything.
$ 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
The issue is port 443 is open for all traffic
How do I make the backend working with HTTPS?
You can try the code below: