You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

代理服务器与主服务器间Token身份认证实现及存储方案咨询

实现Node.js代理与主服务器间的HTTPS及服务器级Token认证方案

一、先搞定HTTPS基础配置(保障通信加密)

因为你要的是代理和主服务器之间的端到端通信安全,所以代理服务器和三台主服务器都必须配置HTTPS,不能只在代理端做加密。

  • 证书获取:测试环境可以用openssl生成自签证书;生产环境一定要用正规CA机构签发的证书(比如Let's Encrypt免费证书),避免浏览器或客户端报不安全提示。
  • Node.js配置:用https模块替代http模块创建服务器,传入证书和私钥文件,示例代码会包含这部分细节。

二、服务器级Token认证的实现逻辑

服务器级认证和用户端认证不同,核心是代理服务器在转发请求时携带专属身份Token,主服务器验证Token合法性后才处理请求,具体步骤如下:

1. 生成安全的服务器Token

用Node.js内置的crypto模块生成足够长的随机字符串,确保难以被暴力破解:

const crypto = require('crypto');
const serverToken = crypto.randomBytes(32).toString('hex'); // 生成64位十六进制字符串,足够安全

这个Token是代理和主服务器之间的"专属密钥",只有双方知晓。

2. 代理服务器转发请求时携带Token

在代理转发请求的钩子(比如http-proxy-middlewareonProxyReq)里,给请求添加自定义HTTP头(比如X-Server-Token),将Token放入其中。

3. 主服务器添加Token验证中间件

在主服务器的所有业务路由之前,添加一个全局中间件,专门验证请求头里的Token:

  • 检查请求头是否包含X-Server-Token字段
  • 对比存储的合法Token,匹配则放行请求,不匹配直接返回403 Forbidden

代码示例

代理服务器(基于http-proxy-middleware)

const https = require('https');
const { createProxyMiddleware } = require('http-proxy-middleware');
const fs = require('fs');
require('dotenv').config(); // 加载环境变量

// HTTPS配置
const proxyHttpsOptions = {
  key: fs.readFileSync('./ssl/proxy-private-key.pem'),
  cert: fs.readFileSync('./ssl/proxy-certificate.pem'),
};

// 代理配置(可根据路由规则分发到不同主服务器)
const proxyMiddleware = createProxyMiddleware({
  target: 'https://your-main-server-1:3000', // 示例主服务器地址
  changeOrigin: true,
  secure: true, // 生产环境开启,验证主服务器的SSL证书
  onProxyReq: (proxyReq) => {
    // 给转发的请求添加服务器Token
    proxyReq.setHeader('X-Server-Token', process.env.SERVER_AUTH_TOKEN);
  },
});

// 启动HTTPS代理服务器
https.createServer(proxyHttpsOptions, proxyMiddleware).listen(443, () => {
  console.log('HTTPS代理服务器已启动在443端口');
});

主服务器(基于Express框架)

const express = require('express');
const https = require('https');
const fs = require('fs');
require('dotenv').config();

const app = express();

// HTTPS配置
const serverHttpsOptions = {
  key: fs.readFileSync('./ssl/main-server-private-key.pem'),
  cert: fs.readFileSync('./ssl/main-server-certificate.pem'),
};

// Token验证中间件
const validateServerAuth = (req, res, next) => {
  const incomingToken = req.headers['x-server-token'];
  const validToken = process.env.SERVER_AUTH_TOKEN;

  if (!incomingToken || incomingToken !== validToken) {
    return res.status(403).json({ error: '未授权的服务器请求' });
  }
  next(); // 验证通过,继续处理业务请求
};

// 全局应用验证中间件
app.use(validateServerAuth);

// 业务路由示例
app.get('/api/data', (req, res) => {
  res.json({ message: '主服务器返回的数据', data: [] });
});

// 启动HTTPS主服务器
https.createServer(serverHttpsOptions, app).listen(3000, () => {
  console.log('主服务器已启动在3000端口');
});

三、Token的存储位置(安全优先+易管理)

绝对不能把Token硬编码到代码里!推荐按环境区分存储方案:

测试环境

  • 环境变量文件:借助dotenv包,创建.env文件写入SERVER_AUTH_TOKEN=你的Token,代码中通过process.env.SERVER_AUTH_TOKEN读取。务必把.env加入.gitignore,禁止提交到版本库。

生产环境

优先选择以下方案(安全性从高到低排序):

  1. 云服务商Secrets管理服务:比如AWS Secrets Manager、Google Cloud Secret Manager、Azure Key Vault。这类服务加密存储Token,支持自动轮换,服务器启动时通过API拉取,完全避免Token暴露。
  2. 容器/编排平台的Secrets资源:比如Docker的--env参数、Kubernetes的Secrets。Token不会写入镜像或配置文件,运行时注入,比本地环境变量更安全。
  3. 加密配置文件:如果必须存在文件中,要用AES等算法加密配置文件,服务器启动时读取并解密,但这种方式维护成本高,仅作为备选。

额外注意事项

  • 定期轮换Token:建议每1-3个月更换一次Token,避免Token泄露后被长期滥用。用Secrets管理服务可自动实现轮换。
  • IP白名单限制:主服务器可配置防火墙,只允许代理服务器的IP地址访问,和Token验证形成双重保障。
  • 禁用HTTP端口:确保代理和主服务器只监听HTTPS端口(443或自定义端口),彻底禁止未加密的HTTP通信。

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

火山引擎 最新活动