How to enable HTTPS on a localhost Node.js Server All In One

发布时间 2023-09-19 20:22:53作者: xgqfrms

How to enable HTTPS on a localhost Node.js Server All In One

locahost HTTPS

errors ❌

clientError =
 [Error: 4056C15DF87F0000:error:0A000416:SSL routines:ssl3_read_bytes:sslv3 alert certificate unknown:../deps/openssl/openssl/ssl/record/rec_layer_s3.c:1584:SSL alert number 46
] {
  library: 'SSL routines',
  reason: 'sslv3 alert certificate unknown',
  code: 'ERR_SSL_SSLV3_ALERT_CERTIFICATE_UNKNOWN'
}
# $ openssl req -nodes -new -x509 -keyout server.key -out server.cert
// Generating a 2048 bit RSA private key

$ openssl req -x509 -newkey rsa:2048 -keyout server_key_temp.pem -out server_cert.pem -days 365
// Generating a 2048 bit RSA private key
$ openssl rsa -in server_key_temp.pem -out server_key.pem
# phrase === 1234567
$ openssl req -x509 -sha256 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365

Generating a 4096 bit RSA private key
.......................++++
.................................................................................................................++++
writing new private key to 'key.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) []:CN
State or Province Name (full name) []:SH
Locality Name (eg, city) []:SH
Organization Name (eg, company) []:
Organizational Unit Name (eg, section) []:
Common Name (eg, fully qualified host name) []:
Email Address []:

$ openssl rsa -in key.pem -out decrypt_key.pem


自签名证书 localhost 不好使了 bug ❌

https://www.cnblogs.com/xgqfrms/p/13845919.html

solution ✅

Let's Encrypt - Free SSL/TLS Certificates

# OpenSSL TLS 1.3
$ openssl req -x509 -out localhost.crt -keyout localhost.key \
  -newkey rsa:2048 -nodes -sha256 \
  -subj '/CN=localhost' -extensions EXT -config <( \
   printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")

https://letsencrypt.org/zh-cn/docs/certificates-for-localhost/

demos

HTTPS 默认的端口 443 ✅ 自动重定向

https://localhost:443/api?id=1 => https://localhost/api?id=1

import https from 'node:https';
import fs from 'node:fs';
import express from 'express';
import chalk from 'chalk';

import bodyParser from 'body-parser';

const app = express();
const port = 443;
const options = {
  key: fs.readFileSync('./localhost.key'),
  cert: fs.readFileSync('./localhost.crt'),
};

// const options = {
//   // Error: error:1C800064:Provider routines::bad decrypt
//   // key: fs.readFileSync('./server_key_temp.pem'),
//   key: fs.readFileSync('./server_key.pem'),
//   cert: fs.readFileSync('./server_cert.pem'),
// };
// const options = {
//   // ❌ Error: error:1C800064:Provider routines::bad decrypt
//   // key: fs.readFileSync('./key.pem'),
//   key: fs.readFileSync('./decrypt_key.pem'),
//   cert: fs.readFileSync('./cert.pem'),
//   // key: fs.readFileSync('./key.pem', 'utf8'),
//   // cert: fs.readFileSync('./cert.pem', 'utf8'),
// };

// parse request `application/x-www-form-urlencoded`
// app.use(bodyParser.urlencoded({ extended: false }));
// parse request `application/json`
app.use(bodyParser.json());

app.get(`/api`, (req, res) => {
  console.log(`req.query`, req.query);
  // req.query { id: '1' }
  res.json({
    https: true,
    port,
  })
});

// https://localhost:443/api?id=1 => https://localhost/api?id=1
// HTTPS 默认的端口 443 ✅

app.post(`/api/:id`, (req, res) => {
  console.log(`req.params`, req.params);
  console.log(`req.body`, req.body);
  // req.query { id: '1' }
  // req.body { id: 7 }
  const {id} = req.params;
  res.json({
    https: true,
    port,
    id,
  });
});

/* 

const url = `https://localhost:443/api/1`;
const json = await fetch(url, {
  body: JSON.stringify({id: 7}),
  headers: {
    "Content-Type": "application/json",
  },
  method: "POST",
}).then(res => res.json());
console.log(`post json =`, json);

*/

const server = https.createServer(options, app);
server.listen(port, () => {
  // const color = chalk.green('Hello world!');
  const color = chalk.green.bgGreen('Hello world!');
  console.log(`color log`, color);
  console.log(`https server is running on: https://localhost:${port}/`);
  console.log(chalk.magenta(`[API]: `) + chalk.green('PORT : [ 443 ]'));
});

server.on("clientError", (error, socket) => {
  console.log(`❌ clientError =\n`, error);
});


image

This page is secure (valid HTTPS).

image

(? 反爬虫测试!打击盗版⚠️)如果你看到这个信息, 说明这是一篇剽窃的文章,请访问 https://www.cnblogs.com/xgqfrms/ 查看原创文章!

refs



©xgqfrms 2012-2021

www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!

原创文章,版权所有©️xgqfrms, 禁止转载 ?️,侵权必究⚠️!