hapi-auth-cookie未覆盖默认TTL问题求助(hapi16.6.2+插件v7.0.0)
我太懂你这个痛点了——开启keepAlive后,本想根据用户的“记住我”选择设置不同的会话时长,结果每次请求都会被默认TTL覆盖,完全达不到预期效果。这是因为keepAlive的默认行为是每次请求都会将cookie的TTL重置为策略初始化时的默认值,不管你登录时临时设置了什么。
下面是针对hapi 16.6.2 + hapi-auth-cookie 7.0.0的可行解决方案:
核心思路
利用keepAlive的函数式配置,动态决定是否要重置TTL:
- 给会话添加一个
rememberMe标记,区分普通会话和“记住我”会话 - 当会话是“记住我”类型时,跳过
keepAlive的TTL重置;普通会话则保持自动续期
具体实现代码
1. 初始化认证策略
server.register(require('hapi-auth-cookie'), (err) => { if (err) throw err; server.auth.strategy('session', 'cookie', { cookie: 'your-session-cookie', password: 'your-strong-encryption-password', // 要求至少32位长度 redirectTo: '/login', ttl: 2 * 60 * 60 * 1000, // 默认普通会话时长:2小时 keepAlive: function(request, session) { // 只有非“记住我”会话,才启用keepAlive自动续期 return !session.rememberMe; }, isSecure: process.env.NODE_ENV === 'production' // 生产环境务必开启HTTPS }); server.auth.default('session'); });
2. 登录控制器处理“记住我”逻辑
server.route({ method: 'POST', path: '/login', handler: function(request, reply) { const { username, password, remember } = request.payload; // 替换成你的实际用户验证逻辑 const isValidUser = validateUser(username, password); if (!isValidUser) { return reply('Invalid credentials').code(401); } // 构建会话数据,加入rememberMe标记 const sessionData = { userId: 'user-123', // 替换为真实用户ID rememberMe: !!remember }; // 设置会话 request.cookieAuth.set(sessionData); // 根据“记住我”选项设置对应TTL if (remember) { // 15天的毫秒数 request.cookieAuth.ttl(15 * 24 * 60 * 60 * 1000); } return reply.redirect('/dashboard'); } });
为什么这样有效?
- 当用户选择“记住我”时,会话里会带上
rememberMe: true,keepAlive函数返回false,不会在每次请求时重置TTL,15天的时长会一直生效 - 普通会话没有
rememberMe标记,keepAlive返回true,每次请求都会把TTL重置为默认的2小时,保持会话自动续期
额外注意事项
- 加密密码
password必须足够强(至少32位),这是hapi-auth-cookie的强制要求 - 生产环境一定要开启
isSecure,避免cookie被明文传输 - 如果需要更细粒度的控制,可以在
keepAlive函数里添加更多判断逻辑,比如基于用户角色或会话剩余时长
内容的提问来源于stack exchange,提问作者Anto S
相关产品推荐
相关产品推荐

