当前位置: 首页 > 后端技术 > Node.js

如何通过cookie和session认证(nodejs-koa)

时间:2023-04-03 19:39:59 Node.js

http是无状态协议,每个请求都是独立的,即使同一个页面向服务器发送多个请求,服务器也无法区分是否是同一个用户,所以此时,您可以使用cookies进行身份认证。当用户登录成功后,服务器为浏览器设置一个cookie,在后续的请求中,浏览器发送请求时,会携带该cookie。需要注意的是,cookie只有在同源请求下才会被发送。设置cookie时,还有以下值属性可以选择,分别是过期时间和范围。如果不设置过期时间,则cookie的生命周期只处于会话阶段。当浏览器关闭时它将被删除。通过max-age或expires设置,cookie的生命周期在有效期内,超过有效期将被删除。范围可以设置域和路径。domain表示指定哪些主机可以接收cookie。如果未设置,则默认为原点。只有当前域名有效。Available,path用于指定host下的哪个路径可以接受cookies。浏览器通过document.cookie获取和设置cookies。当需要在浏览器中使cookie失效时,可以设置max-age=0document.cookie='name=alice;max-age=5'//max-age在浏览器端的单位是秒。在服务端,通过nodejs中的http模块设置响应头信息setCookie,第二次请求会在请求头中携带cookie。如果你对nodejs不熟悉,可以参考这篇文章。在nodejs中如何使用http创建服务consthttp=require('http')constserver=http.createServer((req,res)=>{res.setHeader('Set-Cookie',['age=16;max-age=20000'])//nodejs中max-age的单位是毫秒res.end('cookie')})koa使用ctx.cookies.set和ctx.cookies.get分别设置和获取cookies,以下代码表示,当访问localhost:7000/login时,服务器为浏览器设置cookie,当访问localhost:7000/user时,服务器获取浏览器的cookie。对koa不熟悉的可以参考这篇文章让nodejs启动服务更简单——koa篇constKoa=require('koa')constapp=newKoa()constRouter=require('koa-router')constrouter=newRouter()router.get('/login',(ctx,next)=>{ctx.cookies.set('wheater','sunny',{maxAge:60*1000})ctx.body='setcookie'})router.get('/user',(ctx,next)=>{constcookie=ctx.cookies.get('wheater')ctx.body=cookie})app.use(router.routes())app.use(router.allowedMethods())app.listen(7000,()=>{console.log('Enableservice')})使用nodejs中的http模块响应请求,需要自己处理复杂的逻辑,很多操作都可以通过koa来简化。比如koa自动添加了HttpOnly的属性。上面cookie中存储的数据都是明文形式,非常不安全。在实际应用中,需要对用户信息进行处理。加密处理,此时可以考虑使用session,session也为浏览器填充了cookie值,但是它可以对填充的cookie进行加密constKoa=require('koa')constRouter=require('koa-router')constSession=require('koa-session')constapp=newKoa()constrouter=newRouter()//signed:true添加一个sessionid签名文件sessionid.sigconstsession=Session({key:'sessionId',maxAge:60*1000,有符号:true},app)app.keys=['alice']app.use(session)router.get('/login',(ctx,next)=>{constid=1;constname='lucy'ctx.session.user={id,name}ctx.body='setsession'})router.get('/user',(ctx,next)=>{ctx.body=ctx.session.user//{id:1,name:'lucy'}})app.use(router.routes())app.use(router.allowedMethods())app.listen(7000,()=>{console.log('Enableservice')})session以base64编码存储形式中,可以被解码,也不是完全安全的,所以设置key通过signed:true来添加一个加密的sessionid.sig,这样服务器会验证cookie中设置的session数据的真实性验证上面的cookie和session可以用来进行身份验证,但是这种方式存在以下问题:1.每次请求都会携带cookie,无形中增加了带宽。2.cookie的容量只有4kb。复杂的要求可能还不够。3、在浏览器外的其他客户端,不会主动携带cookie,需要手动设置cookie和session,所以不同终端对cookie的处理存在差异。4.如何处理分布式系统和服务器集群可以保证其他系统也能正确解析session。也有问题。比如在java中,每个服务器获取的会话密钥不同。基于以上问题,越来越多的开发者会使用token进行身份验证。Next这篇文章仔细介绍了token是如何验证的~