You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cloudflare+Heroku托管Express.js站点的SSL配置及HTTPS处理咨询

Great question! Let's break this down step by step so you can get your HTTPS and SSL setup sorted without unnecessary hassle.

Do You Need to Buy a Self-Signed Certificate? Absolutely Not

Forget about purchasing or generating self-signed certificates for your production setup—both Cloudflare and Heroku provide free, browser-trusted SSL certificates that cover all your needs:

  • Cloudflare uses Let's Encrypt to issue free SSL certs for your domain. You just need to enable SSL in their dashboard (we'll cover the best modes below).
  • Heroku's Automated Certificate Management (ACM) automatically provisions and renews free SSL certs for Hobby dynos once you've configured a custom domain. No manual uploads or purchases required.
  • Self-signed certs only make sense for local testing; they trigger big red security warnings in browsers for real users, so they're totally unsuitable for production.

How Cloudflare + Heroku Handle HTTPS/SSL

The key here is understanding that Cloudflare acts as a reverse proxy between your users and Heroku. Here's the typical request flow:
User → Cloudflare (HTTPS) → Heroku (HTTP/HTTPS, depending on your Cloudflare SSL mode)

Choose one of these SSL modes in Cloudflare's dashboard based on your security needs:

  • Flexible Mode: Cloudflare handles HTTPS with the user, then forwards requests to Heroku over HTTP. This is the easiest setup, but note the connection between Cloudflare and Heroku isn't encrypted.
  • Full Mode: Cloudflare uses HTTPS to connect to Heroku. Since Heroku provides its own trusted SSL cert, this keeps the entire request chain encrypted—this is the sweet spot for most users.
  • Full (Strict) Mode: Same as Full, but Cloudflare verifies Heroku's certificate is valid and trusted. This is the most secure option, and it works seamlessly with Heroku's ACM certs.

Adjusting Your Backend Code for HTTPS

The good news? You don't need to switch your Node.js server to use the https module directly if you're using Cloudflare or Heroku's SSL termination. The proxy handles all the encryption, then forwards requests to your server over HTTP. That said, there are a few tweaks to make sure your app behaves correctly:

Since Heroku/Cloudflare act as reverse proxies, your server can stay on HTTP. But you need to tell your Express app to trust the proxy headers so it recognizes the original request was over HTTPS:

// Add this line if you're using Express (which it looks like you are, given the `app` variable)
app.set('trust proxy', true);

This makes req.protocol return https instead of http, which is important for things like generating correct URLs or enforcing HTTPS.

To enforce HTTPS (redirect any accidental HTTP requests to HTTPS), add this middleware:

app.use((req, res, next) => {
  if (req.protocol !== 'https') {
    return res.redirect(`https://${req.get('host')}${req.url}`);
  }
  next();
});

Option 2: Switch to the https Module (Only If Necessary)

If you need to run HTTPS directly on your server (bypassing the proxy), you'd need access to certificate files. However, Heroku doesn't let you download their ACM certs, so this is only feasible if you upload a custom cert to Heroku. Here's what that code would look like:

const https = require('https');
const fs = require('fs');

// Load your certificate and private key files
const sslOptions = {
  key: fs.readFileSync('./private-key.pem'),
  cert: fs.readFileSync('./certificate.pem')
};

// Create an HTTPS server instead of HTTP
const server = https.createServer(sslOptions, app);

Again, this is unnecessary for your Cloudflare + Heroku setup—stick with Option 1 for simplicity.

Your Modified Code Example

Here's how your code would look with the recommended tweaks:

const PORT = process.env.PORT || 8000;
const http = require('http');
const chalk = require('chalk');

// Trust proxy headers from Cloudflare/Heroku
app.set('trust proxy', true);

// Enforce HTTPS redirects
app.use((req, res, next) => {
  if (req.protocol !== 'https') {
    return res.redirect(`https://${req.get('host')}${req.url}`);
  }
  next();
});

const server = http.createServer(app);
const io = require('socket.io')(server);
require('./socket')(io);

server.listen(PORT, () => {
  console.log(chalk.blue('Server started on port', chalk.magenta(PORT)));
});

Socket.io and HTTPS

No changes needed for Socket.io! Since Cloudflare and Heroku handle the SSL termination, WebSocket connections (used by Socket.io) will automatically work over wss:// (the secure WebSocket protocol) as long as your client connects using the correct HTTPS URL. You don't need to modify your Socket.io server setup at all.

Final Checks

  • Double-check your Cloudflare SSL mode is set to "Full" or "Full (Strict)" for maximum security.
  • On Heroku, confirm your custom domain is configured correctly and ACM is enabled (it's automatic for Hobby dynos with custom domains).
  • Never use self-signed certificates in production for this setup—stick with the free, trusted certs from Cloudflare and Heroku.

内容的提问来源于stack exchange,提问作者hopelessmuffins

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:44:55