node 后端代理服务器

分析攻击日志,有几种常见的攻击手段:

上传webshell
远程执行命令漏洞
sql注入
xxs 攻击
试探各种开源框架爆出来的漏洞
分析攻击信息的特点
说白了就是采用web渗透技术,利用http请求,黑客想尽办法,在http header ,body,等部分植入非法的命令,非法字符常见的有:exe,cmd,powershell,download,select,union,delete等等。

解决问题思路
我们能不能开发个代理服务器,来分析http请求header,body里面的信息,如果有非法字符,就截断,拒绝服务。
配置允许请求的白名单,拒绝非法Url.
在这里插入图片描述http proxy 拦截非法请求,拒绝服务。
技术选型
常见的代理服务器有nginx,apache,不知道这2个代理服务器能不能灵活的配置,过滤,转发,没有深入了解。
因此选用nodejs http-proxy。

nodejs优点
轻量级
快速部署
灵活开发
高吞吐,异步io
编码实现逻辑图

在这里插入图片描述

以下有代码分享
var util = require('util'),
    colors = require('colors'),
    http = require('http'),
    httpProxy = require('./node_modules/http-proxy');
    fs = require("fs");

var welcome = [
    '#    # ##### ##### #####        #####  #####   ####  #    # #   #',
    '#    #   #     #   #    #       #    # #    # #    #  #  #   # # ',
    '######   #     #   #    # ##### #    # #    # #    #   ##     #  ',
    '#    #   #     #   #####        #####  #####  #    #   ##     #  ',
    '#    #   #     #   #            #      #   #  #    #  #  #    #  ',
    '#    #   #     #   #            #      #    #  ####  #    #   #   '
].join('\n');

Date.prototype.Format = function(fmt) { //author: meizz
    var o = {
        "M+": this.getMonth() + 1, //月份
        "d+": this.getDate(), //日
        "h+": this.getHours(), //小时
        "m+": this.getMinutes(), //分
        "s+": this.getSeconds(), //秒
        "S": this.getMilliseconds() //毫秒
    };
    if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
        if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
}


// 非法字符
var re = /php|exe|cmd|shell|select|union|delete|update|insert/;
/** 这里配置转发
 */
var proxyPassConfig = {
    "/hello": "http://www.qingmiaokeji.cn ",
    "/": "http://127.0.0.1/"
}

var logRootPath ="g:/httpproxy/";

console.log(welcome.rainbow.bold);

function getCurrentDayFile(){
    // console.log(logRootPath+"access_"+(new Date()).Format("yyyy-MM-dd")+".log");
    return logRootPath+"access_"+(new Date()).Format("yyyy-MM-dd")+".log";
}




//
// Basic Http Proxy Server
//
var proxy = httpProxy.createProxyServer({});
var server = http.createServer(function (req, res) {
    appendLog(req)

    var postData = "";
    req.addListener('end', function(){
        //数据接收完毕
        console.log(postData);
        if(!isValid(postData)){//post请求非法参数
            invalidHandler(res)
        }
    });
    req.addListener('data', function(postDataStream){
        postData += postDataStream
    });



    var result = isValid(req.url)
    //验证http头部是否非法
    for(key in req.headers){
        result = result&& isValid(req.headers[key])
    }

    if (result) {

        var patternUrl = urlHandler(req.url);
        console.log("patternUrl:" + patternUrl);
        if (patternUrl) {
            proxy.web(req, res, {target: patternUrl});
        } else {
            noPattern(res);
        }

    } else {
        invalidHandler(res)
    }


});

proxy.on('error', function (err, req, res) {
    res.writeHead(500, {
        'Content-Type': 'text/plain'
    });

    res.end('Something went wrong.');
});

/**
 * 验证非法参数
 * @param value
 * @returns {boolean} 非法返回False
 */
function isValid(value) {
    return re.test(value) ? false : true;
}

/**
 * 请求转发
 * @param url
 * @returns {*}
 */
function urlHandler(url) {
    var tempUrl = url.substring(url.lastIndexOf("/"));
    return proxyPassConfig[tempUrl];
}

function invalidHandler(res) {
    res.writeHead(400, {'Content-Type': 'text/plain'});
    res.write('Bad Request ');
    res.end();
}


function noPattern(res) {
    res.writeHead(404, {'Content-Type': 'text/plain'});
    res.write('not found');
    res.end();
}


function getClientIp(req){
    return req.headers['x-forwarded-for'] ||
            req.connection.remoteAddress ||
            req.socket.remoteAddress ||
            req.connection.socket.remoteAddress;
}


function appendLog(req) {
    console.log("request url:" + req.url);
    var logData = (new Date()).Format("yyyy-MM-dd hh:mm:ss")+" "+getClientIp(req)+" "+req.method+ " "+req.url+"\n";
    fs.exists(logRootPath,function(exists){
        if(!exists){
            fs.mkdirSync(logRootPath)
        }
        fs.appendFile(getCurrentDayFile(),logData,'utf8',function(err){
            if(err)
            {
                console.log(err);
            }
        });
    })
}

console.log("listening on port 80".green.bold)
server.listen(80);
<think>嗯,用户想了解如何使用Node.js开发微信小程序的后端。首先,我需要回忆一下之前提供的引用内容,看看有没有相关的步骤或教程。引用1提到搭建Node.js环境,引用2有详细的教程步骤,引用3和4涉及Node.js后端与数据库的连接,引用5是关于微信支付的实现。用户可能需要一个从环境搭建到具体功能实现的完整指南。 首先,用户可能需要知道环境配置,比如安装Node.js和npm,验证安装是否正确。然后,创建项目结构,初始化npm,安装Express框架。接着,如何设置路由和处理请求,连接数据库比如MongoDB或者MySQL。可能还需要与小程序前端的交互,比如处理登录、支付等功能。需要分步骤讲解,确保结构清晰。 还要考虑用户可能遇到的常见问题,比如跨域处理、接口调试、安全性等。是否需要提到使用中间件如body-parser或者cors?引用2提到使用WebStorm,但可能用户更常用的是VS Code,是否需要推荐工具?另外,部署和优化也是重要部分,比如使用PM2或者Nginx,但用户的问题主要集中在开发教程,可能部署部分可以简要带过。 需要确保每一步都有代码示例,比如创建一个简单的Express服务器,定义路由,连接数据库,实现增删改查。同时,结合微信小程序的特点,比如如何处理微信登录,获取用户信息,支付接口的调用。引用5中的支付代码可以作为示例,但要解释清楚后端如何生成支付参数。 可能还需要提到RESTful API的设计,如何与前端小程序通信,数据格式使用JSON。此外,调试工具如Postman的使用,以及如何在小程序中调用后端接口。引用4提到了Vue.js,但小程序前端可能使用原生开发,所以需要区分前后端的职责。 最后,是否需要推荐一些第三方库或模块,比如使用jsonwebtoken进行身份验证,或者使用mongoose操作MongoDB?确保教程的实用性和可操作性,用户能跟着步骤一步步实现。可能还需要在相关问题中引导性能优化、部署、具体功能实现等问题,帮助用户深入探索。</think>### 微信小程序 Node.js 后端开发教程 #### 一、开发环境搭建 1. **安装 Node.js 环境** - 访问[Node.js官网](https://nodejs.org/)下载并安装 LTS 版本 - 验证安装成功: ```bash node -v # 输出版本号如 v18.x.x npm -v # 输出版本号如 9.x.x ``` - 全局安装常用工具(如 Express 脚手架): ```bash npm install -g express-generator nodemon ``` 2. **项目初始化** ```bash mkdir wechat-backend && cd wechat-backend npm init -y npm install express body-parser cors mongoose axios ``` #### 二、基础服务器搭建 1. **创建入口文件 `app.js`** ```javascript const express = require('express'); const bodyParser = require('body-parser'); const cors = require('cors'); const app = express(); // 中间件配置 app.use(cors()); // 解决跨域问题 app.use(bodyParser.json()); // 示例路由 app.get('/api/test', (req, res) => { res.json({ code: 200, message: '服务已连通' }); }); // 启动服务器 const PORT = 3000; app.listen(PORT, () => { console.log(`Server running on http://localhost:${PORT}`); }); ``` 通过 `node app.js` 启动服务,访问 `http://localhost:3000/api/test` 测试接口[^2]。 --- #### 三、连接数据库(以 MongoDB 为例) 1. **安装 MongoDB 驱动** ```bash npm install mongoose ``` 2. **数据库连接配置** ```javascript const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost:27017/wechat_db', { useNewUrlParser: true, useUnifiedTopology: true }) .then(() => console.log('MongoDB 连接成功')) .catch(err => console.error('数据库连接失败:', err)); ``` 3. **定义数据模型** ```javascript const userSchema = new mongoose.Schema({ openid: { type: String, required: true, unique: true }, nickname: String, lastLogin: { type: Date, default: Date.now } }); const User = mongoose.model('User', userSchema); ``` --- #### 四、实现核心功能 1. **用户登录接口** ```javascript app.post('/api/login', async (req, res) => { const { code } = req.body; // 小程序前端获取的临时登录凭证 // 调用微信接口获取 openid(需配置小程序 AppID 和 Secret) const wxResponse = await axios.get( `https://api.weixin.qq.com/sns/jscode2session?appid=YOUR_APPID&secret=YOUR_SECRET&js_code=${code}&grant_type=authorization_code` ); const { openid } = wxResponse.data; // 保存或更新用户信息 const user = await User.findOneAndUpdate( { openid }, { lastLogin: new Date() }, { upsert: true, new: true } ); res.json({ code: 200, data: user }); }); ``` 2. **支付接口(参考微信支付文档)** ```javascript app.post('/api/create-payment', async (req, res) => { // 生成支付参数(需接入微信商户平台) const params = { appid: '小程序AppID', mch_id: '商户号', nonce_str: Math.random().toString(36).substr(2), body: '商品描述', out_trade_no: '订单号', total_fee: 100, spbill_create_ip: '用户IP', notify_url: '支付回调地址', trade_type: 'JSAPI' }; // 签名生成逻辑(需使用商户密钥) res.json({ paymentParams: params }); }); ``` 小程序端通过 `wx.requestPayment` 调用支付[^5]。 --- #### 五、调试与部署 1. **本地调试** - 使用 Postman 测试接口 - 配置微信开发者工具中「不校验合法域名」用于本地开发 2. **生产环境部署** ```bash npm install pm2 -g pm2 start app.js --name wechat-backend ``` 建议配合 Nginx 反向代理和 HTTPS 配置[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值