构建NestJS应用程序我想通过https路由所有传入流量,而不会给用户带来不便。
到目前为止,我知道有两种方法,都不符合我的要求。
-
为http和https设置两个服务器,然后按路由/api端点重定向流量,这确实不是DRY,也不是最佳做法。文档重定向
-
通过只创建https服务器,用户将总是被迫手动键入我不想要的https地址。文档https
理想情况下,我会假设一个解决方案,即在某个人第一次访问服务器时,只需键入example.com
即可检查并强制使用https。我认为这最好在我的NestJS应用程序的main.ts
中完成。
对于生产版本,您可能会使用nginx。Nginx将在端口80上侦听并重定向到nestJS端口。此解决方案的优点是易于重定向到https。在你的配置中,你可以放一些类似的东西
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;
...
}
因此,每个http请求都将重定向到https。您的应用程序不必关心http请求,因为它们中的每一个之前都会被重定向。
对于我的用例,在节点http服务器功能齐全的情况下,我认为没有理由膨胀具有反向代理层的服务器。由于这个问题和NestJS有关,所以我在这里介绍一个简单的本地解决方案,使用Nest中间件。当然,u还必须遵循关于托管两台服务器的NestJS文档,这同样相当简单。
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();
}
}
}
我们只是在请求对象上询问连接是否安全,如果不安全,我们会促使浏览器永久重定向到同一个url,但这次以https://
为前缀。然后针对AppModule
的configure()
方法内的所有路由注册上述中间件类。
configure(consumer: MiddlewareConsumer)
{
consumer.apply(HttpsRedirectMiddleware).forRoutes("*");
}