前后端鉴权之session-cookie
@
前后端鉴权之session-cookie
什么是Cookie?
Cookie 就是访问者在访问网站后留下的一个信息片段。它存储在客户端(通常来说是浏览器)。你可以把cookie当作一个map,里边是键值对,每个键值对有过期时间、域、路径、脚本可否访问等描述信息;描述信息存储在客户端,客户端请求时,默认会带上cookie的名称和值,不会带描述信息,通过http请求报文header中的cookie项进行传输;服务器响应时,可以设置cookie信息,就在http响应报文的header中Set-Cookie项。
关于Cookie的详细了解请参考——一文了解cookie
什么是Session?
客户端请求服务端,服务端会为这次请求开辟一块内存空间,这个对象便是 Session 对象,存储结构为 ConcurrentHashMap。Session 弥补了 HTTP 无状态特性,服务器可以利用 Session 存储客户端在同一个会话期间的一些操作记录。
session 和 cookies 是有联系的,session 就是服务端在客户端 cookies 种下的session_id, 服务端保存session_id所对应的当前用户所有的状态信息。每次客户端请求服务端都带上cookies中的session_id, 服务端判断是否有具体的用户信息,如果没有就去调整登录。
Session 的存储方式
服务端只是给 cookie 一个 sessionId,而 session 的具体内容(可能包含用户信息、session 状态等),要自己存一下。存储的方式有几种:
Redis(推荐):内存型数据库,redis中文官方网站。以key-value的形式存,正合sessionId-sessionData的场景;且访问快。- 内存:直接放到变量里。一旦服务重启就没了
- 数据库:普通数据库。性能不高。
node.js 下的 session 处理
服务端要实现对 cookie 和 session 的存取,实现起来要做的事还是很多的。在npm中,已经有封装好的中间件,比如 express-session - npm。它主要实现了:
- 封装了对
cookie的读写操作,并提供配置项配置字段、加密方式、过期时间等。 - 封装了对
session的存取操作,并提供配置项配置session存储方式(内存/redis)、存储规则等。 - 给
req提供了session属性,控制属性的set/get并响应到cookie和session存取上,并给req.session提供了一些方法。
简单实现
// server.js
const express = require('express')
const cookieParser = require('cookie-parser')
// 自动操作 cookie
const session = require('express-session')
// 创建服务器应用程序
const app = express()
// 公开指定目录
app.use('/public/', express.static('./public/'))
app.use(cookieParser())
app.use(session({ // 配置参数
secret: 'xiaan', // 加密口令
resave: true, // 重新储存,每一次 session 修改的时候都会从重新存储
saveUninitialized: false // 默认 true, 未初始化的时候需不需要存储内容
}))
//当服务器收到 get 请求 / 的时候, 执行回调处理函数
app.get('/index', (req, res) => {
console.log(req.session)
// 判断是否登录,如果未登录则重定向到登录
if (req.session.name !== '夏安') return res.redirect('/login')
res.send('我已经登录') // 中文框架会自动解析字符串编码格式
})
app.get('/login', function (req, res) {
req.session.name = '夏安'
res.send('请先登录')
})
app.listen(3000, () => {
console.log("http://localhost:3000");
})
缺点
cookies安全性不好,攻击者可以通过获取本地cookies进行欺骗或者利用cookies进行CSRF攻击。cookies在多个域名下,会存在跨域问题session的信息是保存在服务端上面的,当我们node.js在stke部署多台机器的时候,需要解决共享session,所以引出来session持久化问题,所以session不支持分布式架构,无法支持横向扩展,只能通过数据库来保存会话数据实现共享。如果持久层失败会出现认证失败。
参考:

浙公网安备 33010602011771号