前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
  • 基础篇

    • 环境搭建
    • node部署
    • 基础应用
  • 内置模块

    • 1.0 本地路径处理 path
    • 2.0 文件系统操作 fs
    • 3.1 基础调试 console
    • 3.2 本地调试远程服务器上的Node代码
    • 4.1 网络服务 http
    • 4.2 网络服务 http res
    • 4.3 网络服务 http req
    • 4.4 网络服务 http server
    • 4.5 网络服务 http client
    • 4.6 网络服务 https
    • 4.7 网络TCP net
    • 4.8 网络UDP dgram
    • 4.9 域名解析 dns
    • 5.0 网络地址解析 url
    • 5.1 URL查询字符串 querystring
    • 6.1 流操作 stream
    • 6.2 逐行读取 readline
    • 7.1 进程相关 process
    • 7.2 子进程 child
    • 8.1 二进制数据 buffer
    • 8.2 二进制解码 string_decoder
    • 9.1 事件机制 events
    • 9.2 实用工具模块 util
    • 9.3 数据加密 crypto
    • 9.4 MD5入门介绍及crypto模块的应用
    • 9.4 资源压缩 zlib
    • 9.5 集群 cluster
    • 9.6 v8
  • 进阶篇

    • 5分钟入门非对称加密用法
    • cluster
    • cookie_parser深入
    • crypto模块之理论篇
    • express+cookie_parser签名机制深入剖析
    • express+session实现简易身份认证
    • https
    • log4js入门实例
    • node8_napi
    • 使用 async 控制并发
    • 使用 eventproxy 控制并发
    • 使用 superagent 与 cheerio 完成简单爬虫
    • 基于express+muter的文件上传
    • 将图片转成datauri嵌入到html
    • 常用中间件 body_parser 实现解析
    • 日志模块morgan
    • 服务端字符编解码&乱码处理 charset_enc_dec
    • 测试用例mocha,should,istanbul
    • 调试日志打印debug模块
  • Express

    • 1.1 Express概览篇
    • 1.2 Express
  • Koa2

    • 1.0 koa2概览篇
    • 1.1 快速开始
    • 1.2 async await使用
    • 1.3 koa2简析结构
    • 1.4 koa中间件开发与使用
    • 10.1 单元测试
    • 11.1 开发debug
    • 12.1 快速启动
    • 12.2 框架设计
    • 12.3 分层操作
    • 12.4 数据库设计
    • 12.5 路由设计
    • 12.6 webpack4环境搭建
    • 12.7 使用react
    • 12.8 登录注册功能实现
    • 12.9 session登录态判断处理
    • 13.1 import export使用
    • 2.1 原生koa2实现路由
    • 2.2 koa router中间
    • 3.1 GET请求数据获取
    • 3.2 POST请求数据获取
    • 3.3 koa bodyparser中间件
    • 4.1 原生koa2实现静态资源服务器
    • 4.2 koa static中间件
    • 5.1 koa2使用cookie
    • 5.2 koa2实现session
    • 6.1 koa2加载模板引擎
    • 6.2 ejs模板引擎
    • 7.1 busboy模块
    • 7.2 上传文件简单实现
    • 7.3 异步上传图片实现
    • 8.1 mysql模块
    • 8.2 async await封装使用mysql
    • 8.3 项目建表初始化
    • 9.1 原生koa2实现JSONP
    • 9.2 koa jsonp中间件
  • 其他

    • 操作数据库
    • Session 与 Token
    • Cookie、Session、Token、JWT
    • Socket

# express+cookie_parser签名机制深入剖析

30 秒速记

  • cookie 签名不是加密:值还是明文,只是后面加了一段 HMAC,防的是篡改不是偷看
  • cookie-parser:res.cookie('uid', 'zhang', { signed: true }) 写出来是 s:zhang.签名
  • 校验通过的值放 req.signedCookies,被改过的变成 false,没签名的在 req.cookies
  • express-session 也是同一套:cookie 里存签过名的 sessionId,数据放服务端 store
  • secret 泄露 = 谁都能伪造合法 cookie,要立刻换;secret 可以传数组,第一个用来签,其余用来验,平滑轮换

cookie-parser 的签名机制说白了就是在 cookie 值后面附一段用 secret 算出来的 HMAC,服务端收到后重算一遍对比,对不上就说明被改过。 比如 res.cookie('uid', 'zhang', { signed: true }),浏览器里看到的是 s:zhang.xxxx,前面的 zhang 还是明文,所以签名防的是篡改不是泄露,敏感信息照样不能放。读的时候签名正确的值在 req.signedCookies.uid 里,被改过的会变成 false。express-session 也用同一个库给 sessionId 签名,真正的用户数据放在服务端,cookie 里只有一个改不了的编号。

理解「express+cookie_parser签名机制深入剖析」时,要先明确输入、运行阶段和可观察输出。这里的交互实验会分别执行正常路径与失败路径,并把 Node.js 的关键状态变化和同屏代码对应起来;不能只记命令名称。

工程中还要验证退出码、资源清理和异常输入。属于 security 场景的配置应保持最小可复现,并在开发环境与 CI 中使用相同命令复跑,避免把平台差异或隐式默认值带到线上。

cookie-parser 和 express-session 底层都用 cookie-signature 这个小库做签名,原理就是 HMAC-SHA256:用 secret 对 cookie 值算一段摘要,转成 base64 去掉末尾的 =,拼在值后面。为了标记这是签过名的值,写入 cookie 时前面再加一个 s: 前缀。

下面这段可以直接运行,看清签名长什么样、篡改后会怎样:

const signature = require('cookie-signature')
const secret = 'my-secret'

const signed = signature.sign('zhang', secret)
console.log(signed) // zhang.<一串 base64>

console.log(signature.unsign(signed, secret)) // zhang
// 改掉值、保留签名
const forged = 'admin.' + signed.split('.')[1]
console.log(signature.unsign(forged, secret)) // false
@前端进阶之旅: 代码已经复制到剪贴板

放到 Express 里:

const express = require('express')
const cookieParser = require('cookie-parser')
const app = express()
app.use(cookieParser('my-secret'))

app.get('/login', (req, res) => {
  res.cookie('uid', 'zhang', { signed: true, httpOnly: true })
  res.send('ok') // 浏览器里看到 uid=s%3Azhang.xxxx
})

app.get('/me', (req, res) => {
  const uid = req.signedCookies.uid // 被改过就是 false
  if (!uid) return res.status(401).send('未登录')
  res.send('hi ' + uid)
})
app.listen(3000)
@前端进阶之旅: 代码已经复制到剪贴板

几个结论:签名后的值仍是明文,只能防篡改;被篡改的签名 cookie 在 req.signedCookies 里是 false,不会跑到 req.cookies 里去;secret 是整个机制的根,泄露了等于任何人都能签出合法 cookie。直接在 cookie 里放 uid 还有一个问题是没法让某个登录态主动失效,所以正式的登录态一般用 express-session:cookie 里只放签过名的随机 sessionId,用户信息和过期时间都在服务端,退出登录时删掉服务端记录就行。

面试官追问

追问 1签名 cookie 里的 uid=zhang 浏览器能直接看到,这不是泄露吗?
参考回答

是能看到,签名本来就不管保密,只保证改了会被发现。所以签名 cookie 里只放无所谓被看见的标识,敏感信息要么放服务端 session,要么另外加密。

追问 2测试把签名 cookie 里的 zhang 改成 admin,服务端会发生什么?
参考回答

cookie-parser 重算 HMAC 对不上,req.signedCookies.uid 直接是 false。业务代码要判断这个值,false 一律当未登录处理,别回头去 req.cookies 里取未签名的值兜底。

追问 3secret 不小心提交到公开仓库了,怎么处理才不把用户都踢下线?
参考回答

secret 支持数组:cookieParser(['newSecret', 'oldSecret']),新签发的用 newSecret,旧 cookie 还能用 oldSecret 验过。过一个会话有效期后把旧的删掉。不过如果怀疑已经有人伪造 cookie,就不能平滑了,直接换掉并让所有会话失效。

追问 4用了 express-session,还需要再挂 cookie-parser 吗?
参考回答

从 express-session 1.5 开始就不需要了,它自己解析和签名 cookie。非要一起用的话,两边的 secret 必须一致,否则 sessionId 验签会失败。

追问 5签名比对为什么要用常量时间比较?
参考回答

普通字符串比较遇到第一个不同字符就返回,响应时间会泄露签名对了几位,理论上可以被逐位试出来。cookie-signature 内部做了防时序的比较,自己实现签名时要用 crypto.timingSafeEqual。

# 写在前面

30 秒速记

  • 这篇的主线:先理清 session 和 cookie 的关系,再拆 express-session 怎么实现登录态
  • cookie 是浏览器端存的小数据,每次请求自动带上;session 是服务端存的数据,靠 cookie 里的 id 找到
  • express-session 的核心配置:secret、store、saveUninitialized、resave、cookie.maxAge
  • 登录态三个关注点:防篡改、超时、主动失效
  • express-session 1.5 之后自己处理 cookie,不再依赖 cookie-parser

这一章的路线是先搞清 session 和 cookie 怎么配合,再看 express-session 是怎么把这套配合封装成中间件的。 理解顺序很重要:cookie 存在浏览器、每次请求自动带上,session 存在服务端,两者靠一个 sessionId 对上号。有了这个底子再看 express-session 的配置就好懂了,secret 管 cookie 签名,store 管数据存哪,saveUninitialized 和 resave 管什么时候落盘。最后落到登录态要关心的三件事:cookie 不能被篡改、要会过期、要能主动注销。

本文先简单介绍session跟cookie的区别与联系,接着深入剖析express-session中间件的实现。关于express-session的基础使用,可参见笔者前面的文章。

面试官追问

追问 1有人说 session 和 cookie 是两种互不相关的存储方案,对吗?
参考回答

不对,经典的 session 方案离不开 cookie:服务端存数据,cookie 里存 sessionId,浏览器每次请求带上它,服务端才知道该取哪份数据。两者是配合关系,不是二选一。

追问 2浏览器禁用了 cookie,session 还能用吗?
参考回答

默认的 express-session 就用不了了,因为 sessionId 带不过去。以前有人把 sessionId 拼在 URL 上,但容易泄露,现在一般不这么干;前后端分离的项目多用 Authorization 头带 token。

追问 3给刚接手认证模块的同学安排阅读,顺序怎么排?
参考回答

先跑通一个最小的 express-session 登录示例,在 DevTools 里看 Set-Cookie 和后续请求带的 Cookie;再看配置项各自管什么;最后读中间件源码。基础行为没亲眼见过就读源码,很容易把配置问题当成内部缺陷。

追问 4session 和 JWT 怎么选?
参考回答

session

基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
  • 基础篇

    • 环境搭建
    • node部署
    • 基础应用
  • 内置模块

    • 1.0 本地路径处理 path
    • 2.0 文件系统操作 fs
    • 3.1 基础调试 console
    • 3.2 本地调试远程服务器上的Node代码
    • 4.1 网络服务 http
    • 4.2 网络服务 http res
    • 4.3 网络服务 http req
    • 4.4 网络服务 http server
    • 4.5 网络服务 http client
    • 4.6 网络服务 https
    • 4.7 网络TCP net
    • 4.8 网络UDP dgram
    • 4.9 域名解析 dns
    • 5.0 网络地址解析 url
    • 5.1 URL查询字符串 querystring
    • 6.1 流操作 stream
    • 6.2 逐行读取 readline
    • 7.1 进程相关 process
    • 7.2 子进程 child
    • 8.1 二进制数据 buffer
    • 8.2 二进制解码 string_decoder
    • 9.1 事件机制 events
    • 9.2 实用工具模块 util
    • 9.3 数据加密 crypto
    • 9.4 MD5入门介绍及crypto模块的应用
    • 9.4 资源压缩 zlib
    • 9.5 集群 cluster
    • 9.6 v8
  • 进阶篇

    • 5分钟入门非对称加密用法
    • cluster
    • cookie_parser深入
    • crypto模块之理论篇
    • express+cookie_parser签名机制深入剖析
      • 写在前面
      • session vs cookie vs 登录态
        • 用户登录
        • 登录态检验
      • express-session实现原理
      • 关注点
    • express+session实现简易身份认证
    • https
    • log4js入门实例
    • node8_napi
    • 使用 async 控制并发
    • 使用 eventproxy 控制并发
    • 使用 superagent 与 cheerio 完成简单爬虫
    • 基于express+muter的文件上传
    • 将图片转成datauri嵌入到html
    • 常用中间件 body_parser 实现解析
    • 日志模块morgan
    • 服务端字符编解码&乱码处理 charset_enc_dec
    • 测试用例mocha,should,istanbul
    • 调试日志打印debug模块
  • Express

    • 1.1 Express概览篇
    • 1.2 Express
  • Koa2

    • 1.0 koa2概览篇
    • 1.1 快速开始
    • 1.2 async await使用
    • 1.3 koa2简析结构
    • 1.4 koa中间件开发与使用
    • 10.1 单元测试
    • 11.1 开发debug
    • 12.1 快速启动
    • 12.2 框架设计
    • 12.3 分层操作
    • 12.4 数据库设计
    • 12.5 路由设计
    • 12.6 webpack4环境搭建
    • 12.7 使用react
    • 12.8 登录注册功能实现
    • 12.9 session登录态判断处理
    • 13.1 import export使用
    • 2.1 原生koa2实现路由
    • 2.2 koa router中间
    • 3.1 GET请求数据获取
    • 3.2 POST请求数据获取
    • 3.3 koa bodyparser中间件
    • 4.1 原生koa2实现静态资源服务器
    • 4.2 koa static中间件
    • 5.1 koa2使用cookie
    • 5.2 koa2实现session
    • 6.1 koa2加载模板引擎
    • 6.2 ejs模板引擎
    • 7.1 busboy模块
    • 7.2 上传文件简单实现
    • 7.3 异步上传图片实现
    • 8.1 mysql模块
    • 8.2 async await封装使用mysql
    • 8.3 项目建表初始化
    • 9.1 原生koa2实现JSONP
    • 9.2 koa jsonp中间件
  • 其他

    • 操作数据库
    • Session 与 Token
    • Cookie、Session、Token、JWT
    • Socket
完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

express+cookie_parser签名机制深入剖析|Nodejs专题系列

# express+cookie_parser签名机制深入剖析

30 秒速记

  • cookie 签名不是加密:值还是明文,只是后面加了一段 HMAC,防的是篡改不是偷看
  • cookie-parser:res.cookie('uid', 'zhang', { signed: true }) 写出来是 s:zhang.签名
  • 校验通过的值放 req.signedCookies,被改过的变成 false,没签名的在 req.cookies
  • express-session 也是同一套:cookie 里存签过名的 sessionId,数据放服务端 store
  • secret 泄露 = 谁都能伪造合法 cookie,要立刻换;secret 可以传数组,第一个用来签,其余用来验,平滑轮换

cookie-parser 的签名机制说白了就是在 cookie 值后面附一段用 secret 算出来的 HMAC,服务端收到后重算一遍对比,对不上就说明被改过。 比如 res.cookie('uid', 'zhang', { signed: true }),浏览器里看到的是 s:zhang.xxxx,前面的 zhang 还是明文,所以签名防的是篡改不是泄露,敏感信息照样不能放。读的时候签名正确的值在 req.signedCookies.uid 里,被改过的会变成 false。express-session 也用同一个库给 sessionId 签名,真正的用户数据放在服务端,cookie 里只有一个改不了的编号。

理解「express+cookie_parser签名机制深入剖析」时,要先明确输入、运行阶段和可观察输出。这里的交互实验会分别执行正常路径与失败路径,并把 Node.js 的关键状态变化和同屏代码对应起来;不能只记命令名称。

工程中还要验证退出码、资源清理和异常输入。属于 security 场景的配置应保持最小可复现,并在开发环境与 CI 中使用相同命令复跑,避免把平台差异或隐式默认值带到线上。

cookie-parser 和 express-session 底层都用 cookie-signature 这个小库做签名,原理就是 HMAC-SHA256:用 secret 对 cookie 值算一段摘要,转成 base64 去掉末尾的 =,拼在值后面。为了标记这是签过名的值,写入 cookie 时前面再加一个 s: 前缀。

下面这段可以直接运行,看清签名长什么样、篡改后会怎样:

const signature = require('cookie-signature')
const secret = 'my-secret'

const signed = signature.sign('zhang', secret)
console.log(signed) // zhang.<一串 base64>

console.log(signature.unsign(signed, secret)) // zhang
// 改掉值、保留签名
const forged = 'admin.' + signed.split('.')[1]
console.log(signature.unsign(forged, secret)) // false
@前端进阶之旅: 代码已经复制到剪贴板

放到 Express 里:

const express = require('express')
const cookieParser = require('cookie-parser')
const app = express()
app.use(cookieParser('my-secret'))

app.get('/login', (req, res) => {
  res.cookie('uid', 'zhang', { signed: true, httpOnly: true })
  res.send('ok') // 浏览器里看到 uid=s%3Azhang.xxxx
})

app.get('/me', (req, res) => {
  const uid = req.signedCookies.uid // 被改过就是 false
  if (!uid) return res.status(401).send('未登录')
  res.send('hi ' + uid)
})
app.listen(3000)
@前端进阶之旅: 代码已经复制到剪贴板

几个结论:签名后的值仍是明文,只能防篡改;被篡改的签名 cookie 在 req.signedCookies 里是 false,不会跑到 req.cookies 里去;secret 是整个机制的根,泄露了等于任何人都能签出合法 cookie。直接在 cookie 里放 uid 还有一个问题是没法让某个登录态主动失效,所以正式的登录态一般用 express-session:cookie 里只放签过名的随机 sessionId,用户信息和过期时间都在服务端,退出登录时删掉服务端记录就行。

面试官追问

追问 1签名 cookie 里的 uid=zhang 浏览器能直接看到,这不是泄露吗?
参考回答

是能看到,签名本来就不管保密,只保证改了会被发现。所以签名 cookie 里只放无所谓被看见的标识,敏感信息要么放服务端 session,要么另外加密。

追问 2测试把签名 cookie 里的 zhang 改成 admin,服务端会发生什么?
参考回答

cookie-parser 重算 HMAC 对不上,req.signedCookies.uid 直接是 false。业务代码要判断这个值,false 一律当未登录处理,别回头去 req.cookies 里取未签名的值兜底。

追问 3secret 不小心提交到公开仓库了,怎么处理才不把用户都踢下线?
参考回答

secret 支持数组:cookieParser(['newSecret', 'oldSecret']),新签发的用 newSecret,旧 cookie 还能用 oldSecret 验过。过一个会话有效期后把旧的删掉。不过如果怀疑已经有人伪造 cookie,就不能平滑了,直接换掉并让所有会话失效。

追问 4用了 express-session,还需要再挂 cookie-parser 吗?
参考回答

从 express-session 1.5 开始就不需要了,它自己解析和签名 cookie。非要一起用的话,两边的 secret 必须一致,否则 sessionId 验签会失败。

追问 5签名比对为什么要用常量时间比较?
参考回答

普通字符串比较遇到第一个不同字符就返回,响应时间会泄露签名对了几位,理论上可以被逐位试出来。cookie-signature 内部做了防时序的比较,自己实现签名时要用 crypto.timingSafeEqual。

# 写在前面

30 秒速记

  • 这篇的主线:先理清 session 和 cookie 的关系,再拆 express-session 怎么实现登录态
  • cookie 是浏览器端存的小数据,每次请求自动带上;session 是服务端存的数据,靠 cookie 里的 id 找到
  • express-session 的核心配置:secret、store、saveUninitialized、resave、cookie.maxAge
  • 登录态三个关注点:防篡改、超时、主动失效
  • express-session 1.5 之后自己处理 cookie,不再依赖 cookie-parser

这一章的路线是先搞清 session 和 cookie 怎么配合,再看 express-session 是怎么把这套配合封装成中间件的。 理解顺序很重要:cookie 存在浏览器、每次请求自动带上,session 存在服务端,两者靠一个 sessionId 对上号。有了这个底子再看 express-session 的配置就好懂了,secret 管 cookie 签名,store 管数据存哪,saveUninitialized 和 resave 管什么时候落盘。最后落到登录态要关心的三件事:cookie 不能被篡改、要会过期、要能主动注销。

本文先简单介绍session跟cookie的区别与联系,接着深入剖析express-session中间件的实现。关于express-session的基础使用,可参见笔者前面的文章。

面试官追问

追问 1有人说 session 和 cookie 是两种互不相关的存储方案,对吗?
参考回答

不对,经典的 session 方案离不开 cookie:服务端存数据,cookie 里存 sessionId,浏览器每次请求带上它,服务端才知道该取哪份数据。两者是配合关系,不是二选一。

追问 2浏览器禁用了 cookie,session 还能用吗?
参考回答

默认的 express-session 就用不了了,因为 sessionId 带不过去。以前有人把 sessionId 拼在 URL 上,但容易泄露,现在一般不这么干;前后端分离的项目多用 Authorization 头带 token。

追问 3给刚接手认证模块的同学安排阅读,顺序怎么排?
参考回答

先跑通一个最小的 express-session 登录示例,在 DevTools 里看 Set-Cookie 和后续请求带的 Cookie;再看配置项各自管什么;最后读中间件源码。基础行为没亲眼见过就读源码,很容易把配置问题当成内部缺陷。

追问 4session 和 JWT 怎么选?
参考回答

session 状态在服务端,能随时踢人下线,但多实例要共享 store;JWT 把状态放在 token 里,服务端无状态好扩展,但签出去就收不回来,只能靠短过期加黑名单。后台管理类、需要强制下线的我倾向 session。

# session vs cookie vs 登录态

30 秒速记

  • HTTP 无状态:服务端分不清两次请求是不是同一个人
  • cookie 存浏览器、每次请求自动带上;session 存服务端;两者靠 sessionId 一一对应
  • 类比:cookie 是存包处给你的号码牌,session 是柜子里的包
  • 登录态 = 服务端能通过 cookie 找到一份有效的 session,不是「cookie 里写了用户名」
  • cookie 里直接放 uid 不签名就能被改成别人;多实例部署 session 要放共享 store(比如 Redis)

HTTP 本身记不住你是谁,cookie 和 session 配合起来,才让服务端能认出同一个用户。 可以拿存包处来类比:session 是柜子里存的东西,放在服务端;cookie 是给你的号码牌,放在浏览器,每次来都自动出示。服务端拿号码牌找柜子,找到了就知道你是谁。所以判断登录态不是看 cookie 里写了什么名字,而是看能不能用它找到一份有效的 session。号码牌要防伪造,柜子要有到期清理,这就是后面要讲的签名和超时。

HTTP是无状态的,也就是说,同个用户,多次访问同一个网站,网站无法区分前后访问的是否同个用户。cookie跟session的出现很好的解决了这个问题。

抛开两者的学术定义,从应用的角度来讲,session跟cookie就是一对好基友,可以用来实现用户的身份识别。

session是保存在服务端的小段数据,cookie是保存在用户本地的小段数据,它们一般是一一对应的。

上面的解释比较抽象,先举两个常见的例子:用户登录 和 登录态检验。

← crypto模块之理论篇express+session实现简易身份认证 →

fe