Node怎么运用Cookie和Session进行登录验证


本篇内容主要讲解“Node怎么运用Cookie和Session进行登录验证”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Node怎么运用Cookie和Session进行登录验证”吧!在vies目录下新建login.ejs

html>






Document

登录页面

用户名:
密码:

注意:页面中请求的接口是POST /api/login请求在routes目录下新建login.js,该文件定义login页面的页面路由:

varexpress=require("express");
varrouter=express.Router();

/*GETloginpage.*/
router.get("/",function(req,res,next){
res.render("login");
});

module.exports=router;

app.js中挂载页面路由:

//引入
varloginRouter=require("./routes/login");
//挂载
app.use("/login",loginRouter);

启动项目,访问http://localhost:3000/login正常显示:在services/UserService.js中定义接口的模型(M层):

constUserService={
	//.......
//登录查询
login:(username,password)=>{
	//向数据库查询该用户
returnUserModel.findOne({username,password});
},
};

controllers/UserController.js中定义接口的控制层(C层):

constUserController={
	//......
	//登录验证
login:async(req,res,next)=>{
try{
const{username,password}=req.body;
constdata=awaitUserService.login(username,password);
//console.log(data);
if(data){
res.send({ok:1,msg:"登录成功!",data});
}else{
res.send({ok:0,msg:"用户不存在,登录失败!"});
}
}catch(error){
console.log(error);
}
},
};

routes/users.js中定义Api路由:

//登录校验
router.post("/login",UserController.login);

至此登录页面就搭建好了:在上一节Cookie-Session登录验证工作原理的介绍中我们知道:这个过程显然是比较复杂的,在express中有一个express-session模块可以大大降低我们的工作量,让我们站在巨人的肩膀上开发!下载express-session

npmiexpress-session

app.js中进行配置:

//引入express-session
varsession=require("express-session");

//配置session:需要放在在路由配置的前面
app.use(
session({
name:"AilixUserSystem",//cookie名字
secret:"iahsiuhaishia666sasas",//密钥:服务器生成的session的签名
cookie:{
maxAge:1000*60*60,//过期时间:一个小时过期
secure:false,//为true时表示只有https协议才能访问cookie
},
resave:true,//重新设置session后会重新计算过期时间
rolling:true,//为true时表示:在超时前刷新时cookie会重新计时;为false表示:在超时前无论刷新多少次,都是按照第一次刷新开始计时
saveUninitialized:true,//为true时表示一开始访问网站就生成cookie,不过生成的这个cookie是无效的,相当于是没有激活的信用卡
})
);

配置好后,就会发现浏览器中有一个名为AilixUserSystemcookie:这是因为express-session会自动解析cookie和向前端设置cookie,相当于是图一中的3、6(前半部分:通过SessionId查询到Session ,我们不再需要手动对cookie进行操作。在登录成功时设置session

//controllers/UserController.js
//....
//登录校验
login:async(req,res,next)=>{
try{
const{username,password}=req.body;
constdata=awaitUserService.login(username,password);
//console.log(data);
if(data){
//设置session:向session对象内添加一个user字段表示当前登录用户
req.session.user=data;//默认存在内存中,服务器一重启就没了
res.send({ok:1,msg:"登录成功!",data});
}else{
res.send({ok:0,msg:"用户不存在,登录失败!"});
}
}catch(error){
console.log(error);
}
},

我们向req.session中添加了一个user字段,来保存用户登录的信息,这一步相当于是 图一中的1(SessionId会由express-session模块自动生成)、2req.session是一个session对象,需要注意的是这个对象虽然存在于req中,但其实不同的人访问系统时他们的req.session是不同的,因为 req.session是根据我们设置的cookie(由express-session模块自动生成的AilixUserSystem )生成的,每一个人访问系统所生成的cookie是独一无二的,所以他们的req.session也是独一无二的。在收到请求时校验session,在app.js添加以下代码:

//设置中间件:session过期校验
app.use((req,res,next)=>{
//排除login相关的路由和接口
//这个项目中有两个,一个是/login的页面路由,一个是/api/login的postapi路由,这两个路由不能被拦截
if(req.url.includes("login")){
next();
return;
}
if(req.session.user){
//session对象内存在user,代表已登录,则放行
//重新设置一下session,从而使session的过期时间重新计算(在session配置中配置了:resave:true)
//假如设置的过期时间为1小时,则当我12点调用接口时,session会在1点过期,当我12点半再次调用接口时,session会变成在1点半才会过期
//如果不重新计算session的过期时间,session则会固定的1小时过期一次,无论这期间你是否进行调用接口等操作
//重新计算session的过期时间的目的就是为了防止用户正在操作时session过期导致操作中断
req.session.myData=Date.now();
//放行
next();
}else{
//session对象内不存在user,代表未登录
//如果当前路由是页面路由,,则重定向到登录页
//如果当前理由是api接口路由,则返回错误码(因为针对ajax请求的前后端分离的应用请求,后端的重定向不会起作用,需要返回错误码通知前端,让前端自己进行重定向)
req.url.includes("api")
?res.status(401).send({msg:"登录过期!",code:401})
:res.redirect("/login");
}
});

注意:这段代码需要在路由配置的前面。这段代码中我们通过req.session.myData = Date.now();来修改session对象,从而触发session过期时间的更新(sessionmyData这个属性以及它的值 Date.now()只是我们修改session对象的工具其本身是没有任何意义的),你也可以使用其它方法,只要能将req.session修改即可。因为我们这个项目是后端渲染模板的项目,并不是前后端分离的项目,所以在配置中间件进行session过期校验拦截路由时需要区分Api路由页面路由。后端在拦截API路由后,向前端返回错误和状态码:这个时候需要让前端自己对返回结果进行判断从而进行下一步的操作(如回到登录页或显示弹窗提示),该系统中前端是使用JavaScript内置的fetch来进行请求发送的,通过它来对每一个请求结果进行判断比较麻烦,大家可以自行改用axios,在axios的响应拦截器中对返回结果做统一的判断。向首页(index.ejs)添加一个退出登录的按钮:

为按钮添加点击事件:

constexit=document.getElementById('exit')

//退出登录
exit.onclick=()=>{
fetch("/api/logout").then(res=>res.json()).then(res=>{
if(res.ok){
location.href="/login"
}
})
}

这里调用了GET /api/logout接口,现在定义一下这个接口,在controllers/UserController.js中定义接口的控制层(C层):

constUserController={
	//......
//退出登录
logout:async(req,res,next)=>{
//destroy方法用来清除cookie,当清除成功后会执行接收的参数(一个后调函数)
req.session.destroy(()=>{
res.send({ok:1,msg:"退出登录成功!"});
});
},
};

routes/users.js中定义Api路由:

//退出登录
router.get("/logout",UserController.logout);

前面我们通过 req.session.user = data;设置的session默认是存放到内存中的,当后端服务重启时这些session就会被清空,为了解决这一问题我们可以将session存放到数据库中。安装connect-mongo

npmiconnect-mongo

connect-mongo是MongoDB会话存储,用于用Typescript编写的连接Express。修改app.js

//引入connect-mongo
varMongoStore=require("connect-mongo");

//配置session
app.use(
session({
name:"AilixUserSystem",//cookie名字
secret:"iahsiuhaishia666sasas",//密钥:服务器生成的session的签名
cookie:{
maxAge:1000*60*60,//过期时间:一个小时过期
secure:false,//为true时表示只有https协议才能访问cookie
},
resave:true,//重新设置session后会重新计算过期时间
rolling:true,//为true时表示:在超时前刷新时cookie会重新计时;为false表示:在超时前无论刷新多少次,都是按照第一次刷新开始计时
saveUninitialized:true,//为true时表示一开始访问网站就生成cookie,不过生成的这个cookie是无效的,相当于是没有激活的信用卡
store:MongoStore.create({
mongoUrl:"mongodb://127.0.0.1:27017/usersystem_session",//表示新建一个usersystem_session数据库用来存放session
ttl:1000*60*60,/免费云主机域名/过期时间
}),//存放数据库的配置
})
);

到此,相信大家对“Node怎么运用Cookie和Session进行登录验证”有了更深的了解,不妨来实际操作一番吧!这里是百云主机网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

相关推荐: 如何用C语言代码输出100到200的素数

这篇“如何用C语言代码输出100到200的素数”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“如何用C语言代码输出100到200的素数”文章吧。这…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

(0)
打赏 微信扫一扫 微信扫一扫
上一篇 02/25 10:11
下一篇 02/25 10:12

相关推荐