长风犹在旧人还 2021-04-07 11:09 采纳率: 0%
浏览 187

koa2搭建后台实现登录验证码功能,获取不到session

摸鱼时突发奇想就用koa2搭建了个后台想做个登录功能,百度搜了下怎么搞验证码,其他的都没问题,就是发现session获取不到。

const Koa = require('koa'); //koa
// const Router = require('koa-router'); //koa的路由
const router = require('koa-router')();
const static = require('koa-static'); //静态资源加载
const bodyParser = require('koa-bodyparser'); //解析post请求
const cors = require('koa2-cors'); //解决跨域
const session = require('koa-session');

//实例化
const app = new Koa();
// const router = new Router();
const { routes } = require('./api/user/user');

//设置session
app.keys = ['some secret hurr'];
const CONFIG = {
	key: 'koa:sess', //cookie key (default is koa:sess)
	maxAge: 86400000, // cookie的过期时间 maxAge in ms (default is 1 days)
	overwrite: true, //是否可以overwrite    (默认default true)
	httpOnly: true, //cookie是否只有服务器端可以访问 httpOnly or not (default true)
	signed: true, //签名默认true
	rolling: false, //每次访问将会重置过期时间
	renew: false //(boolean) 会话即将过期时续订会话
};

//注入依赖模块
app.use(cors({ credentials: true })); //解决跨域
app.use(static(__dirname + '/public')); //静态资源
app.use(bodyParser()); //解析post请求
app.use(session(CONFIG, app)); //启动session
app.use(router.routes()).use(router.allowedMethods()); //解析路由

routes.forEach((route) => {
	router[route.type](route.url, route.callback);
});

app.use(router.routes()); /*启动路由*/
app.use(router.allowedMethods());
//开启服务
app.listen(23333, (_) => {
	console.log('server running at http://localhost:23333');
});

这是我的app.js

const svgCaptcha = require('svg-captcha'),
	{ sign } = require('jsonwebtoken'),
	{ secret } = require('../../config/config'),
	fs = require('fs');
let newData = [];

module.exports = {
	routes: [
		{
			type: 'get',
			url: '/login',
			callback: async (ctx) => {
				const query = ctx.query,
					{ name, pwd, captcha } = query;
				let token = '',
					myBody = {};

				if (ctx.session.userinfo) {
					newData = [ctx.session.userinfo];
				}

				if (name === 'qwe' && pwd === 'qwe' && captcha === newData[0]) {
					isSuccess = '0';
					errorMSG = '登录成功';
					token = sign({ name, pwd }, secret, { expiresIn: '1h' });

					myBody = {
						isSuccess: '0',
						token,
						timestamp: new Date().getTime(),
						query
					};
				} else {
					myBody = {
						isSuccess: '1',
						errorMSG: '用户名或密码不正确',
						timestamp: new Date().getTime(),
						query
					};
				}

				ctx.session.ssdasdasd = 'asdad';
				ctx.body = myBody;
			}
		},
		{
			type: 'get',
			url: '/getRouteList',
			callback: async (ctx) => {
				const query = ctx.query;
				let isSuccess = '0',
					errorMSG = '';

				let data = [
					{
						path: '/system',
						component: 'Main',
						deep: 1,
						isFather: true,
						nodeList: [
							{
								path: '/system/jurisdiction',
								component: '/system/jurisdiction',
								deep: 2,
								isFather: false
							},
							{
								path: '/system/role',
								component: '/system/role',
								deep: 2,
								isFather: false
							}
						]
					}
				];

				ctx.body = {
					isSuccess,
					errorMSG,
					data,
					timestamp: new Date().getTime(),
					query
				};
			}
		},
		{
			type: 'get',
			url: '/getImgUrl',
			callback: async (ctx) => {
				const cap = svgCaptcha.create({
						size: 4, // 验证码长度
						width: 160,
						height: 60,
						fontSize: 50,
						ignoreChars: '0oO1ilI', // 验证码字符中排除 0oO1ilI
						noise: 2, // 干扰线条的数量
						color: true, // 验证码的字符是否有颜色,默认没有,如果设定了背景,则默认有
						background: '#eee' // 验证码图片背景颜色
					}),
					clientId = ctx.cookies.get('clientId'),
					captcha = require('../../data/captcha.json');

				let img = cap.data, // 验证码
					text = cap.text.toLowerCase(); // 验证码字符,忽略大小写

				ctx.session.captcha = text;

				ctx.response.type = 'image/svg+xml';

				if (clientId) {
					captcha[clientId] = text;

					// fs.writeFile('../../data/captcha.json');
				}

				ctx.body = img;
			}
		}
	]
};

这是路由表

关于session的配置

设置session

关于前端是用的vue。axios的session设置已经打开了

而且前端验证码都加载出来了,控制台里也没有新增的cookie

  • 写回答

1条回答 默认 最新

  • 憧憬blog 2023-03-14 19:17
    关注

    从你提供的代码和描述来看,可能出现获取不到 session 的原因有几种可能性:

    1. session 中没有存储需要的数据
      在你的代码中,可以看到在获取验证码的接口 /getImgUrl 中,后端将生成的验证码存储在了 session 中:
    ctx.session.captcha = text;
    

    但是在登录接口 /login 中,对于 session 的使用只有一行:

    if (ctx.session.userinfo) {
        newData = [ctx.session.userinfo];
    }
    

    这个代码的意思是如果 session 中存在 userinfo 数据,则将其存储在一个数组 newData 中,但是你并没有在其他地方使用 newData 变量,所以总是获取不到 session 中的数据。你需要在验证码校验的部分中,使用 ctx.session.captcha 获取 session 中的验证码值。

    1. session 配置可能存在问题
      你的代码中设置了 session 配置:
    const CONFIG = {
        key: 'koa:sess', 
        maxAge: 86400000, 
        overwrite: true, 
        httpOnly: true, 
        signed: true, 
        rolling: false, 
        renew: false
    };
    
    app.keys = ['some secret hurr'];
    app.use(session(CONFIG, app)); //启动session
    

    可以看到,session 配置的 key 是 koa:sess,但是在前端 axios 中设置的 cookie 名称是 koa.sid

    Cookie.set('clientId', clientId, {
        expires: moment().add(7, 'days').toDate(),
        path: '/',
        secure: false,
        sameSite: 'lax'
    });
    

    所以,可能存在这样的情况:前端设置的 cookie 名称和后端 session 配置的 key 不一致,导致无法正确读取 session 数据。你可以将 cookie 设置和 session 配置中的名称改为一致的字符串,例如:

    const CONFIG = {
        key: 'koa.sid', 
        maxAge: 86400000, 
        overwrite: true, 
        httpOnly: true, 
        signed: true, 
        rolling: false, 
        renew: false
    };
    
    Cookie.set('koa.sid', clientId, {
        expires: moment().add(7, 'days').toDate(),
        path: '/',
        secure: false,
        sameSite: 'lax'
    });
    

    这样就可以消除该问题可能存在的影响。

    希望我的回答能解决你的问题,如有不清楚的地方可以继续追问哦!

    评论

报告相同问题?

悬赏问题

  • ¥15 小程序中fit格式等运动数据文件怎样实现可视化?(包含心率信息))
  • ¥15 如何利用mmdetection3d中的get_flops.py文件计算fcos3d方法的flops?
  • ¥40 串口调试助手打开串口后,keil5的代码就停止了
  • ¥15 电脑最近经常蓝屏,求大家看看哪的问题
  • ¥60 高价有偿求java辅导。工程量较大,价格你定,联系确定辅导后将采纳你的答案。希望能给出完整详细代码,并能解释回答我关于代码的疑问疑问,代码要求如下,联系我会发文档
  • ¥50 C++五子棋AI程序编写
  • ¥30 求安卓设备利用一个typeC接口,同时实现向pc一边投屏一边上传数据的解决方案。
  • ¥15 SQL Server analysis services 服务安装失败
  • ¥15 基于面向对象的图书馆借阅管理系统
  • ¥15 opencv图像处理,需要四个处理结果图