1. 方案构思
其实,仅仅是中转服务,也可以考虑在原有api的主文件中增加中转逻辑,尤其是原有api与中转逻辑存在管理的情景
2.可行性分析&方案实施
完全可以在原有 API 的主文件中直接增加中转逻辑,尤其是当你的原有 API 和中转逻辑存在相互管理和协调的情景时,这样的设计方式会更加简洁且易于维护。
✅ 在原有 API 中增加中转逻辑的优势:
- 集中管理:所有的服务逻辑都集中在一个地方,便于管理和调试。
- 减少复杂性:不需要单独启动一个额外的中转服务,避免了服务间的协调和多端口监听的复杂性。
- 共享资源:可以直接共享原有 API 的资源、认证逻辑和中间件,避免重复的代码。
- 高效的开发和部署:如果你已经有一个稳定的 API 服务,直接在其基础上增加中转逻辑可以加快开发进度,并且减少部署过程中的中转和负载均衡等问题。
✅ 设计思路:
- 在原有 API 中实现中转逻辑:你可以通过在现有 API 中增加一个新的路由,处理那些需要代理的请求。这个新路由会接收到来自前端的请求,执行相应的处理后,将其转发到真实的 API 服务。
- 与现有逻辑结合:你可以将中转服务与现有的 API 控制器或服务层进行集成,共享已有的验证、授权等逻辑。
原有app.js主文件:
require('dotenv').config();
const axios = require('axios');
const express = require('express')
const app = express()
const Joi = require('joi')
const cors = require('cors') app.use(cors())
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
app.use((req, res, next) => { res.cc = (err, status = 1) => { res.send({ status, message: err instanceof Error ? err.message : err }) } next() })
const { expressjwt } = require('express-jwt')
app.use( expressjwt({ secret: process.env.JWT_SECRET_KEY, algorithms: ['HS256'], getToken: (req) => { const token = req.headers['x-access-token'] if (token && token.startsWith('Bearer ')) { return token.slice(7) } return null } }).unless({ path: [/^\/api\/login(\/.*)?$/, /^\/proxy(\/.*)?$/] }) )
const userRouter = require('./router/user')
app.use('/api', userRouter)
const taskRouter = require('./router/task') app.use('/api', taskRouter)
app.use((err, req, res, next) => { if (err instanceof Joi.ValidationError) return res.cc(err) if (err.name === 'UnauthorizedError') return res.cc('身份认证失败!') res.cc(err) console.error(err) next() })
app.listen(3007, () => { console.log('服务器启动成功: http://127.0.0.1:3007') })
|
其中,增加以下中转逻辑
app.use('/proxy', async (req, res) => { const targetUrl = 'https://imooc.zcwytd.com' + req.originalUrl.replace(/^\/proxy/, '') try { const response = await axios({ method: req.method, url: targetUrl, headers: { ...req.headers, host: 'imooc.zcwytd.com' }, data: req.body }) res.status(response.status).send(response.data) } catch (err) { console.error('代理请求出错:', err.message) res.status(err.response?.status || 500).send({ error: err.message, details: err.response?.data || '无法获取更多信息' }) } })
|
- 需要在 expressjwt.unless 中放行新增的代理路径
✅ 解决方案
修改这段代码中的 unless
配置,让 /hmhrproxy
也豁免掉身份认证:
js复制编辑app.use( expressjwt({ secret: process.env.JWT_SECRET_KEY, algorithms: ['HS256'], getToken: (req) => { const token = req.headers['x-access-token'] if (token && token.startsWith('Bearer ')) { return token.slice(7) } return null } }).unless({ path: [ /^\/api\/login(\/.*)?$/, /^\/proxy(\/.*)?$/, /^\/hmhrproxy(\/.*)?$/ // ✅ 加上这一行,豁免 /hmhrproxy 的中转请求 ] }) )
|
3.重新拉取
在 /var/www/shuangzhao-api-project
目录下,如果要确认本地 Git 分支,可以直接运行:
git branch #确认本地分支 git branch -a #同时看到本地分支和远程分支
git pull #从远程拉取最新代码
|
然后,执行 npm -i
,执行安装!
为了确保正常通信 - 需要建立密钥关系
运行以下命令:
ssh-keygen -t ed25519 -C "youruilin@gmail.com"
|
系统会提示你输入文件保存路径。默认是 /root/.ssh/id_rsa
,如果你不想改变路径,直接按 回车 就行。如果你想自定义路径,可以输入新的文件路径。
Enter file in which to save the key (/root/.ssh/id_rsa): [直接按回车或输入路径]
|
完成密钥生成后,你可以查看生成的公钥(id_rsa.pub
),并将其添加到 GitHub:
接下来,需要将复制的内容添加至 github:
关于node环境确实
Node.js 和 npm 的安装通常会绑定到特定用户的环境中,而当使用 root 用户时,可能无法访问普通用户的配置或安装的工具。因此,解决方法主要是确保你在正确的用户环境下执行命令。
4. 修改nginx规则
# 编辑配置文件 sudo nano /etc/nginx/sites-available/default
|
增加 proxy 字段
# 反向代理本地 API 服务 location /api/ { proxy_pass http://127.0.0.1:3007; # 不加路径,完整转发 /api/** proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }
# 转发代理第三方 API(Node 中转) location /proxy/ { proxy_pass http://127.0.0.1:3007; # /proxy/** 会走 Node 中转 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }
|
Ctrl
+ O
(字母 O)来保存文件,然后Ctrl
+X
退出
测试配置
重新加载 nginx
sudo systemctl reload nginx
|