元素码农
基础
UML建模
数据结构
算法
设计模式
网络
TCP/IP协议
HTTPS安全机制
WebSocket实时通信
数据库
sqlite
postgresql
clickhouse
后端
rust
go
java
php
mysql
redis
mongodb
etcd
nats
zincsearch
前端
浏览器
javascript
typescript
vue3
react
游戏
unity
unreal
C++
C#
Lua
App
android
ios
flutter
react-native
安全
Web安全
测试
软件测试
自动化测试 - Playwright
人工智能
Python
langChain
langGraph
运维
linux
docker
工具
git
svn
🌞
🌙
目录
▶
浏览器架构概览
多进程架构设计
浏览器内核组成
进程间通信机制
沙箱安全机制
浏览器加载页面流程
▶
渲染引擎原理
HTML解析算法
CSSOM构建过程
布局计算原理
图层合成机制
重绘与回流优化
▶
JavaScript引擎
V8执行流水线
事件循环机制
内存管理策略
JIT编译原理
垃圾回收算法
▶
网络栈实现
HTTP协议栈
缓存机制详解
资源加载策略
WebSocket实现
网络安全机制
▶
浏览器存储
Cookie管理机制
Web Storage实现
IndexedDB原理
缓存存储策略
▶
浏览器安全
同源策略实现
发布时间:
2025-03-23 15:45
↑
☰
# Cookie管理机制 ## 概述 Cookie是浏览器存储的重要机制之一,主要用于维护客户端状态信息。本文将详细介绍Cookie的工作原理、安全机制以及最佳实践。 ## 基本概念 ### 1. Cookie结构 #### 属性组成 - name: Cookie名称 - value: Cookie值 - domain: 域名范围 - path: 路径范围 - expires/max-age: 过期时间 - secure: 安全标志 - httpOnly: HTTP访问限制 - sameSite: 跨站点限制 #### 设置示例 ```javascript // 服务端设置Cookie app.get('/api/login', (req, res) => { res.cookie('sessionId', 'abc123', { domain: '.example.com', path: '/', expires: new Date(Date.now() + 86400000), // 1天后过期 secure: true, httpOnly: true, sameSite: 'Strict' }); res.json({ status: 'success' }); }); // 客户端设置Cookie document.cookie = 'theme=dark; max-age=31536000; path=/'; ``` ### 2. 作用域 #### 域名限制 ```javascript // Cookie域名管理 class CookieDomainManager { constructor(domain) { this.domain = domain; } isValidDomain(cookieDomain) { // 检查域名是否符合同源策略 return cookieDomain === this.domain || cookieDomain.endsWith('.' + this.domain); } getEffectiveDomains() { const parts = this.domain.split('.'); const domains = []; for (let i = 0; i < parts.length - 1; i++) { domains.push('.' + parts.slice(i).join('.')); } return domains; } } ``` #### 路径限制 ```javascript // Cookie路径管理 class CookiePathManager { isValidPath(cookiePath, requestPath) { // 规范化路径 cookiePath = this.normalizePath(cookiePath); requestPath = this.normalizePath(requestPath); return requestPath.startsWith(cookiePath); } normalizePath(path) { return path.endsWith('/') ? path : path + '/'; } getEffectivePaths(path) { const paths = ['/']; const parts = path.split('/'); for (let i = 1; i < parts.length; i++) { paths.push(parts.slice(0, i + 1).join('/')); } return paths; } } ``` ## 管理机制 ### 1. 存储管理 #### Cookie存储 ```javascript // Cookie存储管理器 class CookieStore { constructor() { this.cookies = new Map(); } setCookie(cookie) { const key = this.getCookieKey(cookie); // 检查是否超过存储限制 if (this.cookies.size >= 180 && !this.cookies.has(key)) { this.removeOldestCookie(); } this.cookies.set(key, { value: cookie.value, expires: cookie.expires, createdAt: Date.now() }); } getCookie(name, domain, path) { const key = this.getCookieKey({ name, domain, path }); const cookie = this.cookies.get(key); if (cookie && this.isExpired(cookie)) { this.cookies.delete(key); return null; } return cookie; } getCookieKey(cookie) { return `${cookie.name}@${cookie.domain}${cookie.path}`; } isExpired(cookie) { return cookie.expires && cookie.expires < Date.now(); } removeOldestCookie() { let oldest = null; let oldestKey = null; for (const [key, cookie] of this.cookies) { if (!oldest || cookie.createdAt < oldest.createdAt) { oldest = cookie; oldestKey = key; } } if (oldestKey) { this.cookies.delete(oldestKey); } } } ``` #### 大小限制 ```javascript // Cookie大小检查 class CookieSizeChecker { constructor() { this.maxSize = 4096; // 4KB } checkSize(cookie) { const size = this.calculateSize(cookie); return size <= this.maxSize; } calculateSize(cookie) { return encodeURIComponent(cookie.name).length + encodeURIComponent(cookie.value).length + cookie.domain.length + cookie.path.length + // 其他属性的大小 20; // 预留给其他属性的空间 } getAvailableSpace(existingCookies) { const usedSpace = existingCookies.reduce( (total, cookie) => total + this.calculateSize(cookie), 0 ); return this.maxSize - usedSpace; } } ``` ### 2. 安全机制 #### 安全标记 ```javascript // Cookie安全配置 class CookieSecurityConfig { constructor() { this.defaultConfig = { secure: true, httpOnly: true, sameSite: 'Strict' }; } getSecureConfig(options = {}) { return { ...this.defaultConfig, ...options, // 在HTTPS环境下强制使用secure secure: options.secure !== false && this.isHttps() }; } isHttps() { return window.location.protocol === 'https:'; } validateSameSite(value) { const validValues = ['Strict', 'Lax', 'None']; return validValues.includes(value); } } ``` #### 加密处理 ```javascript // Cookie加密 class CookieEncryption { constructor(secretKey) { this.secretKey = secretKey; } async encrypt(value) { const encoder = new TextEncoder(); const data = encoder.encode(value); const key = await crypto.subtle.importKey( 'raw', encoder.encode(this.secretKey), { name: 'AES-GCM' }, false, ['encrypt'] ); const iv = crypto.getRandomValues(new Uint8Array(12)); const encrypted = await crypto.subtle.encrypt( { name: 'AES-GCM', iv }, key, data ); return { data: btoa(String.fromCharCode(...new Uint8Array(encrypted))), iv: btoa(String.fromCharCode(...iv)) }; } async decrypt(encryptedData, iv) { const key = await crypto.subtle.importKey( 'raw', new TextEncoder().encode(this.secretKey), { name: 'AES-GCM' }, false, ['decrypt'] ); const decrypted = await crypto.subtle.decrypt( { name: 'AES-GCM', iv: Uint8Array.from(atob(iv), c => c.charCodeAt(0)) }, key, Uint8Array.from(atob(encryptedData), c => c.charCodeAt(0)) ); return new TextDecoder().decode(decrypted); } } ``` ## 最佳实践 ### 1. 安全配置 - 使用Secure标记 - 启用HttpOnly - 配置SameSite - 设置适当的过期时间 - 使用加密存储敏感数据 ### 2. 性能优化 - 控制Cookie大小 - 使用合适的域名范围 - 及时清理过期Cookie - 避免在静态资源中使用Cookie - 使用其他存储机制替代不必要的Cookie ### 3. 开发建议 - 遵循最小权限原则 - 实施适当的错误处理 - 定期轮换会话Cookie - 使用标准的Cookie库 - 做好安全审计和监控