如何让nodejs应用程序端口从http转到https而不破坏默认的80/443访问路径?

问题描述 投票:0回答:1

在大约12个小时不断尝试很多事情(包括询问副驾驶)之后,我终于放弃并决定问这个问题。 我在服务器上运行 nodejs app.js 时遇到问题。

我的服务器配置如下:

  • 服务器类型:VPS
  • 操作系统:Linux:Ubuntu 24.x
  • WebHost 管理器:Webuzo
  • 应用程序处理程序:Webuzo 的默认值,(尽管它也有“乘客”)
  • SSL:对所有域均存在、有效、强制
  • 应用程序文件:app.js
  • 网络服务器:OpenLiteSpeed
  • 应用程序端口(由处理程序和代码中定义):30000

现在,如果我从 cli 运行

nodemon app.js
或从界面中的应用程序处理程序运行启动。当端口设置为 30000、express 且未配置 https 时,应用程序运行良好。 申请可见于:

  1. example.com - LiteSpeed 将其重定向到 https://example.com(我相信这是反向代理自行工作),因为所有域都强制使用 https。 [注意:这没有实现
    https.createServer
    甚至没有将其导入到我的
    app.js
    文件中]
  2. example.com:30000 - 这可以在 http:// 上访问,这就是我想要在 https:// 上访问的内容,即使有人想在端口 30000 上访问 http:// 。

在我要实现的调试/解决方法中,我在导入 https 并在

https.createServer
中定义
cert
key
文件后添加了
options

现在发生了什么:

  1. example.com:30000 轻松转到 https://example.com:30000。应用程序在那里可以访问/可见。
  2. 但现在我的默认域已损坏,即 http://example.comhttps://example.com 均无法访问(继续加载)。 [似乎 litespeed 反向代理搞砸了]

我的代码:

import https from "https";
import http from "http";
import fs from "fs";
import express from "express";
import path from "path";
import { dirname } from "path";
import url from "url";
import {fileURLToPath} from "url";
import bodyParser from "body-parser";
import morgan from "morgan";
import "dotenv/config";



const app = express();
const httpApp = express();
const __dirname = dirname(fileURLToPath(import.meta.url));


var visitor = 1;
const port = 30000;

app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('public'));


// app.use((req, res, next) => { if (!req.headers.host.startsWith('www.')) { return res.redirect(301, 'https://www.' + req.headers.host + req.url); } next(); }); 


const options = {
    key: fs.readFileSync(path.resolve("example.com.key")),
    cert: fs.readFileSync("example.com.crt"),
    ca: fs.readFileSync(path.resolve("example.com-ca.crt"))
};



const httpsOptions = {
    key: fs.readFileSync("example.com.key"),
    cert: fs.readFileSync("example.com.crt")
};
httpApp.set('port',30001);
httpApp.get("*", function (req, res, next) {
    res.redirect("https://" + req.headers.host + "/" + req.path);
});



function logger(req, res, next){
    console.log("Request method: ", req.method);
    console.log("Request URL:", req.url);
    next();
}


app.use(morgan("tiny"));

//request method
app.use(logger);


app.post("/submit", (req, res) => {
    console.log(req.body);
    console.log(req.body.name);
    var name = req.body.name;
    var email = req.body.email;


    res.send(`<h1>Hey ${name} with email id ${email}, we got your message, unfortunately we are unable to serve at this moment. </h2>`)
});


app.get('/', (req, res) => {
    console.log(visitor);   
    res.sendFile(__dirname + "/public/index.html");
        
    
});





app.get('/test', (meow, bhow) => {
    bhow.send("Testing works on Http2?");
        // bhow.sendStatus(200);

});



app.use((req, res, next) => {


//   res.status(404).render('status');
  res.status(404).send(`<h1><center> The location <a href="https://${req.hostname}${req.originalUrl}">${req.hostname}${req.originalUrl}</a> is not available at this moment. <br><br> That's a 404 Not Found Error</h1></center>
    <center>
    <h2> Let's go back to home @ <a href="https://example.com">${req.hostname}</a></h2></center>`);
});




 




 




const servinginSSL = https.createServer(options, app);

servinginSSL.listen(30000, ()=>{
    console.log("Running at port 30000");
});




// http.createServer((req, res)=>{
//     res.writeHead(301, {"Location": `https://${req.headers.host}${req.url}`});
//     res.end();
// }).listen(30000, () => {
//     console.log("Http server ran and redirecting to HTTPS")
// });




// app.set('port', 30000);
// app.enable('trust proxy');

// http.createServer(httpApp).listen(httpApp.get('port'), function() {
//     console.log('Express HTTP server listening on port ' + httpApp.get('port'));
// });

// https.createServer(httpsOptions, app).listen(30000, function() {
//     console.log('Express HTTPS server listening on port ' + "30000");
// });







// app.listen(port, () => {
//     console.log(`Running at ${port}`);
// });

我尝试了几种解决方案,包括更改代理、重写 litespeed 规则,但没有任何效果。

虽然没有实现

https.createServer
并且只使用
app.listen(30000, ....)
似乎在访问
example.com
时工作正常,它会自动转到
https://example.com
。 我只是担心端口 30000 也可以在没有 http 的情况下访问,这会让我的应用程序直接受到攻击。

我尝试过的 stackoverflow 答案:如何调整我的 NodeJs 服务器代码以响应 HTTPS 请求?

请帮忙。我是一个

node.js express http-redirect https port
1个回答
0
投票

😭 我找到了一种方法,并且它按预期工作。我仍然不确定这是否是正确的方法(因为我是虚拟主机定制和所有方面的新手),但你走吧:

我刚刚在 litespeed 文件夹中编辑了 example.com 端口 80 (

vhost.conf
) 的虚拟主机文件。

我在文件中更改的是一行简单的代码:

extprocessor 30000 {
  type                    proxy
  address                 https://127.0.0.1:30000
  env             NODE_ENV=production
  maxConns                5 
  initTimeout             20
  retryTimeout            20
  respBuffer              0
}

我刚刚将

address 127.0.0.1:30000
更改为地址 https://127.0.0.1:30000

现在,

example.com
是:

  • Firefox - 重定向到
    https://example.com
    没有问题,工作正常。
  • Chrome/Edge/Brave - 重定向到
    https://example.com
    ,没有问题,工作正常。

https://example.com

  1. Firefox - 工作没有问题
  2. Edge/Brave/Chrome - 工作没有问题

http://example.com:30000

https://example.com:30000

  • 适用于所有浏览器。

这是通过 Nodejs 完成的,使用:

https.createServer(options, app).listen(30000, ()=>{
console.log("Running at port 30000");
});

并在选项中:

const options = {
    key: fs.readFileSync(path.resolve("example.com.key")),
    cert: fs.readFileSync("example.com.crt"),
    ca: fs.readFileSync(path.resolve("example.com-ca.crt"))
};

ca 文件可能在控制面板的 ssl 文件夹下不可用。即使我省略 ca 键值对,我的也能工作。

附注昨晚,副驾驶给我提供了一个答案,其中代码要求 http 和 https 监听端口 30000,然后副驾驶自己说一个端口不能分配给两个不同的东西,这让我伤透了脑筋。 😭 我当时就辞去了副驾驶职务。

© www.soinside.com 2019 - 2024. All rights reserved.