服务端鉴权之Session/Cookie
程序员文章站
2024-01-29 18:08:04
...
Cookie
cookie原理
服务端在Header Set-Cookie,然后客户端会自动存取下来(cookie中可以看到)
下次请求,请求头会携带cookie传给后端
const http = require('http')
http
.createServer((req,res)=>{
if(req.url === '/favicon.ico'){
res.end('')
return
}
//观察cookie存在
console.log('cookie:',req.headers.cookie)
//设置cookie
res.setHeader('Set-Cookie','cookie1=aaa')
res.end('hello cookie')
})
.listen(3000)
存储在客户端
传送到服务端
cookie缺点
- 不安全,能在客户端看到(明文),可能被篡改(document.cookie = …)
- 容量限制,只能存很小的数据
- 不能存实例
因为有上面的缺点,不适合做鉴权,需要用session来配合
Session
session原理
浏览器首次访问,生成uid保存在服务端session中,且将uid存储于cookie
下次访问,根据uid对请求进行认证
const http = require('http')
const session = {}
http
.createServer((req,res)=>{
//观察cookie是否存在
console.log('cookie',req.headers.cookie)
//存储一对键值对
const sessionKey = 'uid'
const cookie = req.headers.cookie
if(cookie&&cookie.indexOf(sessionKey)!=-1){
//下次访问
res.end('Come Back')
//使用正则解析是否存在之前的cookie
const pattern = new RegExp(`${sessionKey}=([^;]+);?\s*`)
const uid = pattern.exec(cookie)[1]
console.log('session',uid,session,session[uid])
}else{
//第一次访问
//设置键值对的值,用你需要的规则,这儿用随机数代替
const uid = (Math.random()*9999999999).toFixed()
res.setHeader('Set-Cookie',`${sessionKey}=${uid};`)
//真正的数据
session[uid] = {name:'admin'}
res.end('hello admin')
}
res.end('hello session')
})
.listen(3000)
session优点
- 浏览器只存了一个编号或加密串,很难推定
- 真正的数据,存储于服务端,安全可存实例又无容量限制,可进行鉴权
Koa中实现Session
通过koa-session中间件来实现
const koa = require('koa')
const app = new koa()
const session = require('koa-session')
//签名key keys作用 用来对cookie进行签名
app.keys = ['some secret']
//配置项
const SESS_CONFIG = {
key: "sess", //cookie链名
maxAge: 86400000, // 有效期,默认一天
httpOnly: true, // 只能用于http传输,仅服务器修改,提高安全性
signed: true // 签名cookie,如秘钥
}
//注册
app.use(session(SESS_CONFIG, app))
//测试
app.use(ctx => {
if(ctx.path === '/favicon.ico') return
//获取
let n = ctx.session.count || 0
//设置
ctx.session.count = ++n
ctx.body = '第'+n+'次访问'
})
app.listen(3000)
上面的session存储于变量(内存)中,可能会遇到下面的一些问题
- 内存容量不足
- 无法满足横向扩展(node配置于多台服务器,无法保证下次进来还是上一台服务器)
所以通常情况下需要将session进行全局存储,一般将其存在redis中
redis存储session
redis介绍
一个高性能的key-value数据库
redis缓存产品的三个特点
- 支持数据持久化,可以将内存中的数据保存在磁盘中,重启的适合可以再次加载进行使用
- 不仅支持简单的key-value类型的数据,同时还提供list、set、zset、hash等数据结构的存储
- 支持数据的备份,即master-slave模式的数据备份
redis优势 - 性能极高,由C语言编写,能读的速度是110000次/s,写的速度是81000次/s
- 丰富的数据类型,支持二进制案例的Strings、Lists、Hashes、Sets及Ordered Sets数据类型操作
- 所有操作都是原子性的,即要么成功执行要么失败完全不执行。单个操作是原子性的,多个操作也支持事务,通过MULTI和EXEC指令包起来
- 丰富的特性,支持publish/subscribe,通知,key过期等特性
redis使用
1、github下载
2、解压改名为redis
3、reids-server启动
redis测试
const redis = require('redis')
//连接redis
const client = redis.createClient(6379,'localhost')
//使用事件发射器,检测错误
client.on("error", function (err) {
console.log("Error " + err);
});
//设置
client.set('key','value')
//拿取
client.get('key',(err,v)=>{
if(err) throw err;
console.log('redis get ', v)
})
如果报下面的错误,则表示reids-server未启动
Error Error: Redis connection to localhost:6379 failed - connect ECONNREFUSED 127.0.0.1:6379
koa-redis使用
安装
npm i -S koa-redis
const koa = require('koa')
const app = new koa()
const session = require('koa-session')
const redisStore = require('koa-redis')
const redis = require('redis')
const redisClient = redis.createClient(6379,'localhost')
const wrapper = require('co-redis')
const client = wrapper(redisClient)
//签名key keys作用 用来对cookie进行签名
app.keys = ['some secret']
//配置项
const SESS_CONFIG = {
key: "sess", //cookie链名
maxAge: 86400000, // 有效期,默认一天
httpOnly: true, // 仅服务器修改
signed: true, // 签名cookie
store: redisStore({client}) // 指定存储则会按照你要求的去存储,否则会默认存储到内存中
}
//注册
app.use(session(SESS_CONFIG, app))
app.use(async (ctx,next) => {
const keys = await client.keys('*')
keys.forEach(async key => console.log(await client.get(key)))
await next()
})
//测试
app.use(ctx => {
if(ctx.path === '/favicon.ico') return
//获取
let n = ctx.session.count || 0
//设置
ctx.session.count = ++n
ctx.body = '第'+n+'次访问'
})
app.listen(3000)
session/cookie鉴权的缺点
1、服务端有状态,需要去进行相关存储,若服务器断了,就会刷新内存,重连之后下次请求就会出现问题
2、基于cookie传送,cookie是基于浏览器的,不够灵活。如APP、跨域等其他情况会受限
推荐阅读
-
服务端鉴权之Session/Cookie
-
Symfony2之session与cookie用法小结_php实例
-
怎样操作nuxt框架进行路由鉴权并使用Koa与Session
-
ASP.NET常见对象之Cookie、Session与Application
-
php 之 cookie 跟 session 简单解读(笔记)
-
nuxt框架中路由鉴权之Koa和Session的用法
-
Symfony2之session与cookie用法小结,symfony2cookie
-
Symfony2之session与cookie用法小结
-
Java Web学习之Cookie和Session的深入理解
-
Java Web学习之Cookie和Session的深入理解