103 lines
2.9 KiB
JavaScript
Raw Permalink Normal View History

2025-12-04 10:16:16 +08:00
// 强制清除 Node.js 使用的代理环境变量,避免走 127.0.0.1:10809
process.env.HTTP_PROXY = '';
process.env.HTTPS_PROXY = '';
process.env.http_proxy = '';
process.env.https_proxy = '';
const express = require('express');
const crypto = require('crypto');
const axios = require('axios');
const app = express();
const WECHAT_APPID = 'wx571134046e0268fc';
const WECHAT_SECRET = 'fe427470faf04a4aa8ccb412ac0d2a29';
let access_token = '';
let jsapi_ticket = '';
// 获取 access_token
async function getAccessToken() {
try {
const res = await axios.get(
`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${WECHAT_APPID}&secret=${WECHAT_SECRET}`
);
if (res.data.access_token) {
access_token = res.data.access_token;
console.log('✅ access_token 获取成功');
} else {
throw new Error(JSON.stringify(res.data));
}
} catch (err) {
console.error('❌ 获取 access_token 出错:', err.message);
throw err;
}
}
// 获取 jsapi_ticket
async function getJsapiTicket() {
try {
const res = await axios.get(
`https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${access_token}&type=jsapi`
);
if (res.data.ticket) {
jsapi_ticket = res.data.ticket;
console.log('✅ jsapi_ticket 获取成功');
} else {
throw new Error(JSON.stringify(res.data));
}
} catch (err) {
console.error('❌ 获取 jsapi_ticket 出错:', err.message);
throw err;
}
}
// 生成签名
function createSignature(url) {
const nonceStr = Math.random().toString(36).substr(2, 15);
const timestamp = Math.floor(Date.now() / 1000);
const rawStr = `jsapi_ticket=${jsapi_ticket}&noncestr=${nonceStr}&timestamp=${timestamp}&url=${url}`;
const signature = crypto.createHash('sha1').update(rawStr).digest('hex');
return {
appId: WECHAT_APPID,
timestamp,
nonceStr,
signature
};
}
// 定时刷新 token 和 ticket
async function refreshWeChatConfig() {
try {
await getAccessToken();
await getJsapiTicket();
} catch (err) {
console.error('❌ 微信配置刷新失败');
}
}
setInterval(refreshWeChatConfig, 7000 * 1000);
// 启动初始化
refreshWeChatConfig();
// 签名接口
app.get('/api/wechat-signature', (req, res) => {
const url = req.query.url;
if (!url) {
return res.status(400).json({ error: '缺少 url 参数' });
}
if (!jsapi_ticket) {
return res.status(500).json({ error: 'jsapi_ticket 未准备好,请稍后重试' });
}
const config = createSignature(url);
res.json(config);
});
// 静态资源服务
app.use(express.static(__dirname));
// 启动服务
const port = 3005;
app.listen(port, () => {
console.log(`✅ Server running at http://localhost:${port}`);
});