阶段五:HttpOnly Cookie 登录持久化
从零构建带AI流式对话的Vue2全栈应用-CSDN博客本文是对这篇文章阶段五的讲解一、阶段五为什么要改 Token 保存方式阶段四Token 保存在 Vuex 前端 JavaScript 可以读取 Token 刷新后 Token 消失阶段五Token 保存在 HttpOnly Cookie JavaScript 不能读取 Token 浏览器自动携带 Cookie 刷新后可以恢复登录二、Cookie 是什么Cookie 是浏览器保存的一小段数据。服务器返回Set-Cookie: session_tokenabc123浏览器保存后之后访问同一个网站会自动发送Cookie: session_tokenabc123前端页面不需要自己把 Token 加到请求头。三、cookie-parser安装npm install cookie-parser代码const cookieParser require(cookie-parser) app.use(cookieParser())它会把请求 Cookie 解析到req.cookies例如req.cookies.session_token可以获取会话 Token。四、Cookie 配置const sessionCookieOptions { httpOnly: true, secure: false, sameSite: lax, path: /, maxAge: 24 * 60 * 60 * 1000 }1.httpOnlyhttpOnly: true表示前端 JavaScript 不能读取这个 Cookie。下面代码读不到会话 Tokendocument.cookie这样可以降低恶意脚本直接窃取 Token 的风险。2.securesecure: false表示 HTTP 也允许发送 Cookie。本地项目使用http://localhost所以必须暂时是false。正式上线使用 HTTPS 时应该改为secure: true3.sameSitesameSite: lax用于限制跨网站请求携带 Cookie。它可以减少一部分 CSRF 风险。4.pathpath: /表示这个 Cookie 对整个网站路径都有效。包括/api/users /api/auth/me /api/ai/stream5.maxAgemaxAge: 24 * 60 * 60 * 1000计算过程24 小时 × 60 分钟 × 60 秒 × 1000 毫秒所以保存 24 小时。五、登录成功设置 Cookieres.cookie( SESSION_COOKIE_NAME, token, sessionCookieOptions )可以理解成让响应头包含Set-Cookie: session_tokentoken内容然后后端只返回用户res.json({ code: 0, data: { user: codeRecord.user } })不再返回token因为前端不应该读取 HttpOnly Token。六、阶段五鉴权中间件const token req.cookies[SESSION_COOKIE_NAME]不再读取req.headers.authorization而是读取 Cookie。完整流程浏览器请求 /api/users ↓ 自动携带 Cookie ↓ cookie-parser 解析 ↓ req.cookies.session_token ↓ loginSessions.get(token) ↓ 找到当前用户 ↓ next()七、为什么还需要后端loginSessionsCookie 中只保存一个随机 Tokenabc123真正用户信息保存在后端loginSessions.set(token, { user: mockWechatUser, expiresAt: ... })对应关系abc123 ↓ 微信学习者不能只相信浏览器自己传来的用户名称。应该由后端根据 Token 查找真实用户。八、/api/auth/me的作用刷新页面后Vuex 中currentUser null但浏览器可能仍有有效 Cookie。前端调用GET /api/auth/me浏览器自动带 Cookie。后端返回req.currentUser前端重新把用户放进 Vuex。所以刷新页面 ↓ Vuex 清空 ↓ 调用 /api/auth/me ↓ Cookie 仍有效 ↓ 后端返回用户 ↓ Vuex 恢复 currentUser九、authChecked为什么必要Vuexstate: { currentUser: null, authChecked: false }页面刚启动时currentUser null此时不能立即判断用户没登录因为还没有检查 Cookie。所以增加authChecked含义false还没有询问后端 true已经完成登录状态检查十、Vuex ActioninitializeAuthasync initializeAuth({ state, commit }) { if (state.authChecked) { return Boolean( state.currentUser ) } try { const user await getCurrentUser() commit( setCurrentUser, user ) return true } catch (error) { commit(clearAuth) return false } finally { commit( setAuthChecked, true ) } }参数解构原本 Vuex action 参数是context可以写async initializeAuth(context) { context.state context.commit(...) }这里使用解构async initializeAuth({ state, commit })直接取出state和commit。为什么finally设置authChecked无论Cookie 有效 Cookie 无效 后端错误都说明检查已经完成。所以放在finallycommit(setAuthChecked, true)十一、路由守卫为什么变成 asyncrouter.beforeEach( async (to, from, next) { if (!store.state.authChecked) { await store.dispatch( initializeAuth ) } // 再判断是否登录 } )必须先等待/api/auth/me返回。错误流程currentUser 初始 null 立即判断未登录 跳到登录页 之后 /auth/me 才返回正确流程先等待 /auth/me ↓ 恢复 currentUser ↓ 再判断能否进入后台十二、Axios 的withCredentialsconst service axios.create({ withCredentials: true })它表示请求允许携带 Cookie 等凭证。当前开发代理是同源形式浏览器本来就会携带 Cookie。保留这个配置可以让后续前后端分开部署时更容易调整。十三、退出登录后端loginSessions.delete(token)删除服务器中的会话。然后res.clearCookie( SESSION_COOKIE_NAME, cookieOptions )通知浏览器删除 Cookie。前端commit(clearAuth)清空当前用户。完整退出流程点击退出 ↓ POST /api/auth/logout ↓ 后端删除 session ↓ 后端清除 Cookie ↓ Vuex 清除用户 ↓ 跳转 /login十四、阶段五的限制目前会话保存在const loginSessions new Map()后端一旦重启Map 被清空 浏览器 Cookie 还在 后端找不到对应 session 返回登录失效正式项目通常使用Redis 数据库 Session 服务保存会话。

相关新闻

番茄钟终极指南:如何用Tomodoro实现深度专注与高效时间管理

番茄钟终极指南:如何用Tomodoro实现深度专注与高效时间管理

番茄钟终极指南:如何用Tomodoro实现深度专注与高效时间管理 【免费下载链接】tomodoro A pomodoro web app with PIP mode, white noise generation, tasks and more! 项目地址: https://gitcode.com/gh_mirrors/to/tomodoro 你是否曾坐在电脑前数小时&#…

2026/7/19 14:49:04阅读更多 →
HarmonyOS:ArkTS数据模型的设计与演进实战

HarmonyOS:ArkTS数据模型的设计与演进实战

引子:数据设计好了,UI 就是套模板 星空运势应用经历了两次数据结构的变化。第一版是四个文件——Types.ts、SignsData.ts、TarotData.ts、Constants.ts,每个文件职责单一。重构后合并成了一个 DataModel.ets,12 星座的数据从 5 个…

2026/7/19 14:49:04阅读更多 →
TMS320F2838x DMA通道优先级配置与高优先级模式实战解析

TMS320F2838x DMA通道优先级配置与高优先级模式实战解析

1. 项目概述:为什么DMA优先级配置是嵌入式开发者的必修课在嵌入式系统开发,尤其是基于TMS320F2838x这类高性能实时微控制器的项目中,直接内存访问(DMA)模块的性能直接决定了整个系统的实时性和效率。很多工程师在初次接…

2026/7/19 14:49:04阅读更多 →
视频分析终极指南:如何用AI让机器看懂视频内容

视频分析终极指南:如何用AI让机器看懂视频内容

视频分析终极指南:如何用AI让机器看懂视频内容 【免费下载链接】video-analyzer Analyze videos using LLMs, Computer Vision and Automatic Speech Recognition 项目地址: https://gitcode.com/gh_mirrors/vi/video-analyzer 你是否曾经面对海量视频内容感…

2026/7/19 22:46:53阅读更多 →
LangGraph 是什么?为什么 Agent 需要图结构

LangGraph 是什么?为什么 Agent 需要图结构

前面 RAG 系列里,我们一直在讨论一个问题: AI 应用不只是把问题发给大模型,然后把答案返回给用户。 真正进入业务以后,系统往往需要处理文档检索、工具调用、权限判断、多轮对话、失败重试、人工确认和日志追踪。 这些能力叠在一起…

2026/7/19 22:46:53阅读更多 →
Cursor vs Windsurf 2026:谁才是AI编程之王?

Cursor vs Windsurf 2026:谁才是AI编程之王?

Cursor vs Windsurf 2026深度对比:哪个AI编程助手更适合你? > 一句话结论: Cursor 在代码补全和 Agent 模式上更成熟,Windsurf 在上下文感知和 IDE 集成上更激进。两者都远远甩开了传统编辑器Copilot的组合。至于选哪个——看…

2026/7/19 22:46:53阅读更多 →
synchronized 锁释放时的“竞争“

synchronized 锁释放时的“竞争“

一、先说结论:这里的"竞争"是指多个线程同时试图获取同一把锁,但锁只有一个,最终只有一个能成功,其他失败者必须等待或重试。 你可以把锁想象成一个只能容纳1个人的卫生间,线程就是想上厕所的人。 竞争:多个人同时冲向卫生间,去拉门把手(尝试获取锁)。 抢到…

2026/7/19 22:46:53阅读更多 →
AQS 锁导致cpu飙高原因和synchronized 是一样的吗

AQS 锁导致cpu飙高原因和synchronized 是一样的吗

不完全一样,但本质都是“无效计算”消耗CPU,只是各自的“无效计算”形式不同。 为了让你彻底看透,我从底层机制和CPU消耗路径两个维度来拆解。 一、先看结论:AQS 和 synchronized 的“耗电”路径不同 对比维度 AQS锁(如ReentrantLock) synchronized(重量级锁) CPU消耗…

2026/7/19 22:46:53阅读更多 →
【DWT】计算两不等序列相似度:DWT

【DWT】计算两不等序列相似度:DWT

note DTW(DP-matching)用于计算两个不等长、但变化趋势相关的序列的相似度。论文给出了最优的对齐规则:对称权重 斜率约束P1,让对齐更准,识别错误率降到了原来的2/3针对两个时长不同、采样点数量不一致的语音特征序列…

2026/7/19 22:44:53阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/19 0:01:04阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/19 0:01:04阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/19 0:01:04阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/19 0:01:04阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/19 0:01:04阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/19 0:01:04阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/18 22:49:46阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/19 14:50:26阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/19 18:50:36阅读更多 →