第5章 日志与安全
写入日志
封装函数
js
const fs = require('fs');
const path = require('path');
// 1. 声明创建写入流的函数
const createWriteStream = (filename) => {
// 指定日志的路径
const fullFilename = path.join(__dirname, '../', '../', 'logs', filename);
// 创建写入流
const writeStream = fs.createWriteStream(fullFilename, {
flags: 'a'
});
return writeStream;
};
// 2. 声明写日志的函数
const writeLog = (writeStream, log) => {
writeStream.write(log + '\n');
};
// 3. 声明写入具体日志的函数——如 access log
const accessWriteStream = createWriteStream('access.log');
const access = (log) => {
writeLog(accessWriteStream, log);
};
module.exports = {
access
};
调用函数
js
// 导入 access 函数
const { access } = require('./src/utils/log');
// 调用函数,写入相关日志
access(`${req.method} -- ${req.url} -- ${req.headers['user-agent']} -- ${Date.now()}`);
分析日志
js
// 分析 chrome 用户占比为例
const fs = require('fs');
const path = require('path');
const readline = require('readline');
// 1. 获取文件名
const filename = path.join(__dirname, '../', '../', 'logs', 'access.log');
// 2. 创建读取流
const readStream = fs.createReadStream(filename);
// 3. 创建 readline 对象
const rl = readline.createInterface({
input: readStream
});
let chrome = 0;
let sum = 0;
rl.on('line', (lineData) => {
// 如果该行不存在,直接 return
if (!lineData) {
return;
}
sum++; // 用户总数 +1
const arr = lineData.split(' -- ');
if (arr[2] && arr[2].indexOf('Chrome')) {
chrome++; // 若数组第二项为 Chrome 则 chrome +1
}
});
rl.on('close', () => {
console.log(chrome / sum); // 打印 chrome 的占比
});
SQL 注入
js
// 1. 从 mysql 中导入 escape 函数
const { escape } = require('mysql');
// 2. 将前端传入的参数,使用 escape 处理后再进行插入
const login = (username, password) => {
username = escape(username);
password = escape(password);
const sql = `select username, realname from users where username=${username} and password=${password}`;
return exec(sql).then((rows) => rows[0] || {});
};
XSS 攻击
js
// 1. npm 安装 xss 并导入
const xss = require('xss');
// 2. 将前端传入的参数,使用 xss 处理后再进行插入
const newBlog = (blogData = {}) => {
let { title, content, author } = blogData;
// 使用 xss 处理 title 与 content
title = xss(title);
content = xss(content);
title = escape(title);
content = escape(content);
const sql = `
insert into blogs (title,content,createTime,author)
values (${title}, ${content}, ${createTime}, '${author}')
`;
return exec(sql).then((insertData) => {
return {
id: insertData.insertId
};
});
};
密码加密
封装函数
js
const crypto = require('crypto');
// 密钥
const SECRTE_KEY = '3280RHF23';
// md5 加密
function md5(content) {
let md5 = crypto.createHash('md5');
return md5.update(content).digest('hex');
}
// 加密函数
function genPassword(password) {
const str = `password=${password}&key=${SECRTE_KEY}`;
return md5(str);
}
module.exports = {
genPassword
}
调用函数
js
// 导入 genPassword 函数
const { genPassword } = require('../utils/cryp');
const login = (username, password) => {
// 生成加密密码
password = genPassword(password);
username = escape(username);
password = escape(password);
const sql = `select username, realname from users where username=${username} and password=${password}`;
return exec(sql).then((rows) => rows[0] || {});
};
预览: