主要核心:
1.express-session
2.cookie-parser
3.node自定义中间件
安装第三方插件
npm i express-session cookie-parser
我先描述一下我自己的需求逻辑,首先我在登录页面的时候就链接了一个验证码的接口,获取验证码:
业务是自己设计的 ,也有不合理的地方。
前端代码:
getCaptchaCode(){
axios.get('/getCaptchaCode').then(res=>{
let getCaptchaCode= document.getElementById('getCaptchaCode')
getCaptchaCode.innerHTML = res.data.data.code
})
}
在挂载的时候调用了一下,这个接口随时都可以访问,谁也可以访问,但是除了这个接口,就都需要权限来控制,
我在node服务端这样写了这个接口:
首先看一下我的app.js这个文件,我引入了cookie、session这两个包,主要是对这两个加了签名密钥,相对来讲更加安全一些
//引用session
var session = require("express-session");
var cookieParser = require("cookie-parser")
//用来设置签名密钥
app.use(cookieParser('zjq'))
// express中是把session信息存储在内存中
// 配置session
app.use(session({
secret: "zjq", //设置签名秘钥 内容可以任意填写 但是要和cookieParser相匹
cookie: { maxAge: 60 * 1000 * 60 }, //设置cookie的过期时间,例:80s后 session和相应的cookie失效过期
resave: true, //强制保存,如果session没有被修改也要重新保存
saveUninitialized: false //如果原先没有session那么久设置,否则不设置
}))
这是验证码接口
// 验证码配置信息
const options = {
size: 5, // 验证码长度(显示几个字符)
fontSize: 30, // 验证码的字体大小
ignoreChars: '0o1i', // 验证码字符中排除 0o1i
width: 100, // 验证码的宽度
height: 36, // 验证码的高度
background: '#cc9966', // 验证码的背景颜色
};
//验证码接口
//randomStr 前端发送一个随机的字符
router.get('/getCaptchaCode', (req, res) => {
let randomStr = new Date().getTime() + 'a' + String(Math.floor(Math.random() * (10000 - 9000) + 9000)) + 'a'
req.session.name = randomStr;
res.cookie("name", randomStr, { maxAge: 60*1000*60, signed: true });
console.log(req.session.name,'req.session.name');
let code = captcha.create(options)
console.log(code.text, 'code.text', randomStr);
res.send(endMassage({ data: "验证码获取成功1111", code: code.data, randomStr, session: req.session.name }))
})
生成了时间吹和一个随机数为了更大的减少重复的可能性,然后分别给了cookie的name和session的name,
在这里设置cookie是:
res.cookie("name", randomStr, { maxAge: 60*1000*60, signed: true });
的第一个参数是cookie名,第二个参数cookie名所对应的value,第三个参数是一个对象,maxAge的意思是过期时间,signed是否使用签名密钥。
生成的这两个name,cookie的name会被验证码接口带到前端,
这两个cookie会被浏览器存起来:
这里面的name是我们手动加的,connect.sid是自动生成的,和session有关系,就说req.sessionID;
node自定义中间件
//cookic控制中间件
router.use((req, res, next) => {
req.signedCookies['name'] ? req.signedCookies['name'] : res.send(endMassage({ data: "没有权限", code: 0 }))
req.session.name ? req.session.name : res.send(endMassage({ data: "没有权限", code: 0 }))
if (req.signedCookies['name'] != req.session.name) {
// if (!req.sessionID) {
console.log("没有权限");
res.send(endMassage({ data: "没有权限", code: 0 }))
}
else {
console.log("本次的connect.sid为", req.signedCookies);
// console.log("本次的req.sessionID", req.sessionID);
next()
}
})
在这里进行了判断,取当前的cookie,因为咱们这是取签名密钥的cookie,所以使用
req.signedCookies['name']
的形式来取,主要是signedCookies这个对象。他会给我们将解密好的cookie字段展示。
每一个用户的cookie都是在获取验证码的时候生成的,才有的cookie和session,在访问其他接口的时候没用name字段就直接在中间件中拒绝访问。
下
上面流程图来自网络,如侵权请联系删除。