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
- FreeSSL
/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);
});
This page is secure (valid HTTPS).