You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js应用移动端Cookie不持久,桌面端正常问题求助

Next.js + Iron-Session + TRPC:移动端(iPhone 15)Cookie会话丢失问题排查

问题概述

开发基于Next.js的应用,使用Iron-Session将登录会话存储在Cookie中用于服务器端身份校验。该逻辑在桌面端(本地开发+Google App Engine标准环境部署)均正常,但在iPhone 15的Chrome/Safari浏览器访问部署后的应用时,登录成功后首次请求应用数据时,日志显示Cookie丢失、session为空,用户被强制跳转回首页,仅移动端出现此问题。

已尝试操作

  • 调整Cookie的httpOnly、secure、sameSite参数(测试过strict/lax/none),问题未解决
  • 注释TRPC保护路由中间件、简化路由逻辑,仍存在session为空的情况
  • 日志验证:移动端后续请求的session为空,桌面端正常

排查与解决方案

1. 完善Iron-Session的Cookie配置

首先确认sessionOptions的细节,这是移动端Cookie存储的核心:

export const sessionOptions: IronSessionOptions = {
  password: process.env.IRON_SESSION_PASSWORD!,
  cookieName: 'your-app-session',
  cookieOptions: {
    // 生产环境(GAE)必须设为true,移动端浏览器要求HTTPS环境下的Cookie必须带Secure属性
    secure: process.env.NODE_ENV === 'production',
    // 优先使用lax,none需配合secure: true,但Safari对none的兼容性较差
    sameSite: 'lax' as const,
    // 适配GAE的域名,带前缀点确保子域名可访问
    domain: process.env.NODE_ENV === 'production' ? '.your-app-domain.com' : undefined,
    // 确保全站路由可访问Cookie
    path: '/',
    // 设置合理的过期时间,避免会话过早失效
    maxAge: 60 * 60 * 24 * 7,
    httpOnly: true,
  },
};

关键注意点:

  • GAE环境下secure必须为true,否则移动端浏览器会拒绝存储Cookie
  • 域名设置需匹配GAE的部署域名,带前缀点适配子域名场景

2. 应对Safari智能跟踪防护(ITP)限制

Safari默认开启ITP,会严格限制跨域Cookie或第三方Cookie:

  • 若使用Firebase Auth,确保认证请求与应用域名同域(可配置Firebase自定义域名),避免跨域Cookie被ITP拦截
  • 测试时可临时关闭Safari的“阻止跨站跟踪”功能(设置> Safari> 隐私与安全性),验证是否为ITP导致的Cookie丢失
  • 避免使用长期未使用的Cookie,ITP会自动清除此类Cookie

3. 确保TRPC客户端正确传递Cookie

客户端调用TRPC时,需显式配置credentials: 'include'以传递Cookie:

import { createTRPCNext } from '@trpc/next';
import { httpBatchLink } from '@trpc/client';
import type { AppRouter } from '../server/router';

export const trpc = createTRPCNext<AppRouter>({
  config() {
    return {
      links: [
        httpBatchLink({
          url: '/api/trpc',
          fetch(url, options) {
            return fetch(url, {
              ...options,
              credentials: 'include', // 强制传递Cookie
            });
          },
        }),
      ],
    };
  },
});

4. 验证GAE环境的响应头配置

检查GAE的app.yaml,确保没有额外的安全头阻止Cookie存储:

handlers:
  - url: /.*
    script: auto
    secure: always
    http_headers:
      Strict-Transport-Security: max-age=31536000; includeSubDomains
      # 确保Cookie属性符合要求
      Set-Cookie: SameSite=Lax; Secure; HttpOnly

5. 确认登录流程中Cookie的正确写入

登录成功后必须调用session.save()才能将会话写入Cookie:

async function loginHandler(req: NextApiRequest, res: NextApiResponse) {
  const session = await getIronSession(req, res, sessionOptions);
  // 从Firebase获取认证后的用户信息
  session.user = { id: userId, email: userEmail };
  await session.save(); // 关键步骤:写入Cookie
  res.status(200).json({ success: true });
}

可通过Chrome DevTools(移动端调试)查看登录请求的响应头,确认Set-Cookie字段是否存在且属性正确。

6. 调试移动端Cookie状态

使用Safari Web Inspector连接iPhone调试:

  1. 连接iPhone到Mac,开启手机端Safari的“Web检查器”(设置> Safari> 高级> Web检查器)
  2. Mac端Safari开启开发菜单(偏好设置> 高级> 勾选“在菜单栏中显示开发菜单”)
  3. 在开发菜单中选择对应的iPhone设备和应用页面,查看Application> Cookies,确认会话Cookie是否存在及属性是否正确

补充建议

  • 测试不同iOS版本,确认是否为iOS 17的特定兼容性问题
  • 检查Next.js中间件(middleware.ts),确保未意外修改或删除Cookie
  • 验证Firebase Auth的token解析逻辑,确保用户信息正确写入Iron-Session

内容的提问来源于stack exchange,提问作者shaedopotato

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 11:22:04