Reputation: 783
Building a NestJS Application I want to route ALL incoming traffic through https without inconvenience for the user.
So far there are two ways I know, both doesn't fit my requirements.
Set up two servers for http and https and than redirect traffic per route/api endpoint, which is really not DRY and cannot be best practice. Doc redirect
By only creating the https server, the user would always be forced to type the https address manually what I don't want. Doc https
Ideally I would assume a solution where https is checked and forced the very first moment some one is hitting the server by just typing example.com
. I think this would best be done in main.ts
of my NestJS application.
Upvotes: 5
Views: 6105
Reputation: 371
npm install express-sslify --save
Then, in your main.ts
file:
import enforce from 'express-sslify';
async bootstrap() {
// create your app
// Must be the FIRST middleware applied
// Must add in the 'trustProtoHeader' option
// (I only add this for production, but you can do whatever suits you)
if (process.env.NODE_ENV === 'production') {
app.use(enforce.HTTPS({ trustProtoHeader: true });
}
// other stuff
}
If your NestJS application is hosted on Heroku, you cannot have 2 servers running on an HTTP and HTTPS port. You also cannot simply redirect to https
, because Heorku sends the data from their outward-facing load balancers internally over HTTP traffic, and the app will redirect infinitely.
See Heroku Docs and express-sslify docs, especially the section there regarding Heroku.
Upvotes: 2
Reputation: 836
For my use case, I see no reason to bloat the server with reverse proxy layer while node http servers are fully featured. Since question is related to NestJS, here I present simple native solution, using Nest middleware. Of course, u will have to also follow the NestJS documentation on hosting two servers, which is again fairly simple.
import { HttpStatus, Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response } from "express";
@Injectable()
export class HttpsRedirectMiddleware implements NestMiddleware
{
use(req: Request, res: Response, next: () => void)
{
if (!req.secure)
{
const httpsUrl = `https://${req.hostname}${req.originalUrl}`;
res.redirect(HttpStatus.PERMANENT_REDIRECT, httpsUrl);
}
else
{
next();
}
}
}
We simply ask on request object whether conneciton is secure, if not, we incite browser to permanently redirect to same url, but this time prefixed with https://
.
The middleware class above is then to be registered for all routes within configure()
method of AppModule
.
configure(consumer: MiddlewareConsumer)
{
consumer.apply(HttpsRedirectMiddleware).forRoutes("*");
}
Upvotes: 8
Reputation: 2486
For production release you will probably use nginx. Nginx will be listen on port 80 and redirect to nestJS port. Advantage of this solution is easy redirecting to https. In you config you can put something like this
server {
listen 80;
server_name example1.com example2.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name example1.com example2.com;
...
}
So each http request will be redirect to https. And your application don't have to care about http request because each of them will be redirect before.
Upvotes: 7