// 引入环境变量,尽可能早
require('dotenv').config();
var express = require('express');
var path = require('path');
// 处理用户post请求提交的数据,把数据保存在req.body中。以一个对象的形式提供给服务器,方便进行后续的处理
var bodyParser = require('body-parser');
// 文件读取
var fs = require('fs');
// 可以直接使用req.signedCookies.cname来访问cookie
var cookieParser = require('cookie-parser');
// svg验证码
var svgCaptcha = require('svg-captcha');
// 将session信息存放在服务端,必须要设置数据库保存session
var session = require('express-session');
// 链接redis
var RedisStore = require("connect-redis")(session);
// redis 数据库
const redis = require("redis");
// 请求速率限制
const {RateLimiterRedis, RateLimiterMemory} = require('rate-limiter-flexible');
//跨域
var cors = require('cors');
//http请求
var request = require('request');
//get请求拼接参数
var querystring = require('querystring');
//base编码
var Base64 = require('js-base64').Base64;
//灵活的hashmap
var HashMap = require('hashmap');
// 修改单页面应用浏览器访问时定位到入口文件
const history = require('connect-history-api-fallback');
// 设置与安全相关的 HTTP 响应标头
const helmet = require('helmet');
var Constant = require('./utils/Constant');
//---------------初始化参数start------------------------------------------------------------------
global.rootPath = __dirname;
global.auth_url = Constant.auth_url;
global.server_url = Constant.server_url;
global.local_url = Constant.local_url; //改成自己本机启动express的地址
global.ant_web_url = Constant.ant_web_url;//改成自己本地启动ant前端工程的地址
global.clientId = Constant.clientId; //应用集成平台申请的clientId
global.clientKey = Constant.clientKey; //应用集成平台申请的clientKey
global.c2_api_key = Constant.c2_api_key;
global.app_clientId = Constant.app_clientId;
//token与userid的关系数据集合
global.token2UserIdMap = new HashMap();
//----------------初始化参数end------------------------------------------------------------------
// ---------------自定义工具、路由start---------------------------------------------------------
// 日志
var logger = require('./utils/log_model');
// aes加密、解密
var encryUtils = require('./utils/EncryptionUtils');
// 用户相关工具
var UserUtils = require('./utils/UserUtils');
// 自定义路由
var proxyRouterApi = require('./rourter/proxy');
var productRouter = require('./rourter/product');
var uploadRouter = require('./rourter/upload');
var downloadRouter = require('./rourter/download');
var otherRouter = require('./rourter/other');
const { validRequest } = require('./utils/ValidateUtils');
// ----------------自定义工具、路由end---------------------------------------------------------
// ----------------自定义变量start---------------------------------------------------
// RSA私钥和公钥(!!!注意:私钥不能暴露到外部,必须保留在服务器)
global.rsaPrivateKey = encryUtils.rsa_privateKey();
const rsaPublicKey = encryUtils.rsa_publicKey();
// custom_自定义环境变量
const custom_env = (function(){
const envs= process.env || {};
const customEnvs = {};
Object.keys(envs).forEach(key => {
// 注意:只获取自定义的环境变量,其他环境变量可能包含服务器信息,通过接口返回可能不安全,请谨慎处理
if(typeof key === 'string' && key.startsWith('custom_')){
customEnvs[key] = envs[key]
}
});
return customEnvs;
})();
// 使用到的环境变量
const {
NODE_ENV,
redis_host,
redis_port,
redis_db,
request_limit_enable,
request_limit_points,
request_limit_duration,
request_limit_blockDuration,
request_limit_min_count,
request_sign_reg,
custom_request_sign_enable,
request_sign_ignore,
login_qrcode_appurl,
} = process.env;
// 初始化redis客户端
const redisClient = redis.createClient({
url:`redis://${redis_host}:${redis_port}/${redis_db}`,
// username:'',
// password:'',
});
redisClient.on("error", function(error) {
console.error('redis链接失败',error)
});
redisClient.on("connect", function() {
console.log('redis链接成功')
});
// session使用的store
const redisStore = (function(){
let store = undefined;
store = new RedisStore({
client: redisClient,//redis客户端,必须要指定db
prefix: "webSession:",//在redis中的key名
});
// 初始化时,从存储中删除所有会话
store.clear();
return store;
})();
//请求速率限制
const rateLimiter = (function(){
let limiter = undefined;
if(request_limit_enable === '1'){
limiter = new RateLimiterRedis({
storeClient: redisClient,
keyPrefix: 'rateLimiter',
points: Number(request_limit_points), // 限制周期内的可消耗计数点
duration: Number(request_limit_duration), // 重置计数器周期
blockDuration:Number(request_limit_blockDuration),// 超过计数点的锁定时间
// inMemoryBlockOnConsumed:Number(request_limit_points),// 超过设置的点时,阻止向存储添加计数器
// inMemoryBlockDuration:2,// 阻止向存储添加计数器的时间
insuranceLimiter:new RateLimiterMemory({
points: Number(request_limit_points),
duration: Number(request_limit_duration),
}),//保险,只有当外部存储无法使用时生效
});
}
return limiter;
})()
// ----------------自定义变量end---------------------------------------------------
//-----------------中间件start----------------------------------------------------
var app = express();
// 删除x-powered-by 响应头
app.set('x-powered-by',false)
// 设置与安全相关的 HTTP 响应标头
app.use(helmet({
// 跨域资源策略 "same-origin" | "same-site" | "cross-origin"
crossOriginResourcePolicy: { policy: "same-site" },
}));
// 解析并返回 json格式的数据,content-type默认是application/json才进入这个中间件解析处理
app.use(bodyParser.json({ "limit": "10000mb" }));
// 数据类型为text/*时候会进入这个中间件处理
app.use(bodyParser.text());
// 请求的数据类型是application/x-www-form-urlencoded时才会进入这个中间件进行处理
app.use(bodyParser.urlencoded({ extended: false }));
// 设置cookie时,如果需要使用签名加密,必须在此处设置签名字符串
app.use(cookieParser(clientKey));
// 会话信息存储在服务器,只在cookie中设置sessionid
app.use(session({
name: 'sessionId',
secret: clientKey,//对session数据进行加密的字符串.这个属性值为必须指定的属性(使用cookieParser时,两个中间件的签名需要一致)
resave: true, // session(cookie中存在sessionId的session)没有被修改,也保存session
saveUninitialized: false, // 强制将“新的且未修改”的会话保存到存储中。
rolling:false,//强制在每个响应上设置会话标识符 cookie。 到期重置为原来的maxAge,重置到期倒计时。默认值为false。
cookie: {
maxAge: 1000 * 60 * 60 * 24 * 7,
httpOnly: true,//仅通过 HTTP(S) 而不是客户端 JavaScript 发送
signed: true,//加签
sameSite:true,//是否为同一站点的cookie
},
store:redisStore
}));
// 调试开发时进行跨域设置
app.use(cors({
credentials: true,
origin: ant_web_url,//允许跨域的地址,禁止设置为*
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
headers: 'Authorization,x-requested-with,content-type,content-length,paramSign,sign,requestTime'
}));
// 处理请求静态资源中的gzip文件
app.use(function (req, res, next) {
logger.info('Time--DISPATCH-------------
express中间件当做前端服务器的安全漏洞处理
42 浏览量
2024-02-27
14:15:34
上传
评论
收藏 13KB ZIP 举报
Joker`ssmile
- 粉丝: 116
- 资源: 1
最新资源
- 5G网络基础培训课件.zip
- 2024-spring-HIT-CS-大作业
- yolo目标检测项目实验
- downloadFile-1.hc
- C++课程设计:基于Qt的航班信息管理系统
- ADS7822UVerilog驱动,前面传的有点问题
- 基于python的高性能爬虫程序,使用了多线程+缓存+xpath实现的,这里以彼-岸图库为例,实现,仅用于学习交流
- 中分辨率成像光谱仪(MODIS)烧毁面积产品信息MODIS-C6-BA-User-Guide-1.2.pdf
- Screenshot_20240427_172613_com.huawei.browser.jpg
- 关于学习Python的相关资源网站链接及相关介绍.docx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈