答案:Cookie与Session状态管理
问题: 波比(活动运营)在飞翔官网www.feixiang.net登录后,发现访问hr.feixiang.net时也需要重新登录。请分析原因,并说明如何通过Cookie的Domain属性解决这个问题。
答案:
原因分析
云吞(安全工程师)向波比解释道:这是Cookie的Domain匹配规则导致的。
当波比在www.feixiang.net登录时,服务器设置的Cookie默认Domain属性为www.feixiang.net。根据浏览器的同源策略,Cookie只能被发送到完全匹配的域名或其子域名(当Domain属性显式设置时)。
# 登录响应头(默认情况)
HTTP/1.1 200 OK
Set-Cookie: session_id=abc123; Path=/; HttpOnly; Secure
# 浏览器存储的Cookie Domain为 www.feixiang.net
浏览器发送Cookie的规则是:
- 访问
www.feixiang.net→ Cookie会带上 ✅ - 访问
hr.feixiang.net→ Cookie不会带上 ❌ - 访问
api.feixiang.net→ Cookie不会带上 ❌
因为hr.feixiang.net和www.feixiang.net是同级子域名,不是包含关系,所以Cookie无法共享。
解决方案:设置Domain属性为.feixiang.net
靓晴(UI设计)和凌叔(架构师)讨论后,决定通过显式设置Cookie的Domain属性来实现跨子域名共享登录状态。
将Domain设置为.feixiang.net(注意前面的点,现代浏览器会自动处理),这样该Cookie对feixiang.net及其所有子域名都有效。
# 修改后的登录响应头
HTTP/1.1 200 OK
Set-Cookie: session_id=abc123; Domain=.feixiang.net; Path=/; HttpOnly; Secure; SameSite=Lax
设置后,浏览器在以下域名都会自动带上Cookie:
www.feixiang.net✅hr.feixiang.net✅api.feixiang.net✅admin.feixiang.net✅
飞翔公司的完整实现
鸣哥(DevOps)在飞翔官网的登录服务中做了如下配置:
# Python Flask 示例
from flask import Flask, make_response
app = Flask(__name__)
@app.route('/login', methods=['POST'])
def login():
# 验证用户名密码...
session_id = create_session(user_id)
resp = make_response({'code': 0, 'msg': '登录成功'})
resp.set_cookie(
'session_id',
session_id,
domain='.feixiang.net', # 关键:共享给所有子域名
path='/',
httponly=True, # 防止XSS窃取
secure=True, # 仅HTTPS传输
samesite='Lax', # 防止CSRF攻击
max_age=86400 * 7 # 7天有效期
)
return resp
// Node.js Express 示例
const express = require('express');
const app = express();
app.post('/login', (req, res) => {
const sessionId = createSession(req.body.userId);
res.cookie('session_id', sessionId, {
domain: '.feixiang.net', // 关键:共享给所有子域名
path: '/',
httpOnly: true,
secure: true,
sameSite: 'lax',
maxAge: 86400 * 7 * 1000 // 7天(毫秒)
});
res.json({ code: 0, msg: '登录成功' });
});
安全注意事项
云吞特别提醒:
不要设置Domain为顶级域名(如
.com、.cn),这会导致Cookie被发送到该顶级域下的所有网站,存在严重安全隐患。配合HttpOnly和Secure:防止JavaScript读取Cookie(XSS防护)和确保只在HTTPS下传输。
SameSite属性:设置为
Lax或Strict,防止跨站请求伪造(CSRF)攻击。Session集中存储:使用Redis等集中式Session存储,确保各子域名都能验证Session有效性。
# 查看浏览器中的Cookie(开发者工具控制台)
document.cookie
# 输出:"session_id=abc123" (如果设置了HttpOnly则不可见)
# 在Network面板中查看请求头
Cookie: session_id=abc123
修改后,波比在www.feixiang.net登录后,访问hr.feixiang.net、 admin.feixiang.net等子域名时都能自动保持登录状态,无需重复输入密码,工作效率大大提升。