CSRF 攻击
CSRF 攻击成功的关键是,恶意网站让浏览器自动发起一个请求,这个请求会自动携带 cookie ,正常网站拿到 cookie 后会认为这是正常用户,就允许请求。
防范
如果在请求中加一个字段(CSRF Token),这个字段不会自动携带,正常网站就可以辨别,这个请求是不是由用户自己发起的了
- 用户先发起一个请求给网站,网站提供用户两个字段:set_Cookie、CSRF_Token
- 客户端拿到cookie值 会自动存储在浏览器的 cookie 中
- 客户端拿到CSRF_Token 可以存储到 localstorage 中(服务端通常会保存这个字段在 session 中)
- 用户再次发起请求,点击提交按钮,JS 逻辑将 CSRF_Token 加到请求头中,如:X-CSRF-Token:asfiksakjckkGkuvgsku(这个字段不会随请求自动携带)
- 服务端验证 cookie 值是否正确
- 服务端验证 CSRF_Token 是否正确
CSRF Token 生成库:csurf
// 1 导入 express
const express = require('express')
const cors = require("cors"); // 跨域解决库// 引入用户密码
const userDataBase = require('./xxxxxx.js')// 2 创建一个对象
const app = express(); // --- token
const cookieParser = require("cookie-parser"); // 解析客户端发送过来的 Cookie 头部
const csrf = require("csurf");
var bodyParser = require('body-parser')
// 使用 cookie-parser 中间件 // 使用 csurf 中间件
const csrfProtection = csrf({ cookie: true }); app.use(cookieParser());
app.use(csrfProtection); // ---解析post数据工具
// 使用 express.json() 中间件来解析 JSON 格式的请求体
app.use(express.json());// ----// -----跨域解决方案1 配置 CORS,允许来自 http://localhost:8094 的请求
const corsOptions = { origin: "http://localhost:8094", credentials: true, // 允许携带 cookie
};
app.use(cors(corsOptions));
// ------// 3 获得 csrf token
app.get('/api/get-token', (req, res) => {// 跨域解决方案2 设置头// res.setHeader("Access-Control-Allow-Origin", "*")res.json({ csrfToken: req.csrfToken() });
})// 验证 csrf token
app.post('/api/login', csrfProtection, (req, res) => {// 会验证cookie和x-xsrf-token(cookie需要cookieParser解析)console.log('POST请求成功,CSRF验证通过')
})// 监听端口
app.listen(3000, () => {console.log('服务已启动,端口3000正在监听....')
})