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

Passport.js跨站Cookie问题:Chrome更新后认证服务是否失效及解决方案

跨源认证服务的Cookie问题解答

1. Chrome更新后认证服务会失效吗?

会的。Chrome未来会拦截未分区的第三方Cookie,你的场景里,前端example.com请求后端api.example.com时,后端设置的SameSite=None; Secure会话Cookie会被判定为第三方Cookie(因为跨源),如果没有添加Partitioned属性,更新后Chrome会阻止前端携带这个Cookie到后端,Passport.js无法读取会话ID,自然无法完成用户认证,服务就会失效。

2. 无需变更后端部署位置的解决方案

方案一:给Cookie添加Partitioned属性

给会话Cookie加上Partitioned标记,配合SameSite=None; Secure使用,Chrome会将这个Cookie与前端站点example.com绑定存储,视为“分区Cookie”,不会被第三方拦截规则影响。

如果用express-session(Passport.js依赖的会话中间件),配置示例:

app.use(session({
  store: new RedisStore({ client: redisClient }),
  secret: '你的会话密钥',
  resave: false,
  saveUninitialized: false,
  cookie: {
    secure: true,
    sameSite: 'none',
    partitioned: true, // 关键属性
    maxAge: 24 * 60 * 60 * 1000 // 会话过期时间
  }
}));

这个方案改动最小,只需要添加一个Cookie属性,Passport.js和Redis会话存储不需要额外调整。

方案二:利用同一主域的站点共享Cookie

因为example.com和api.example.com属于同一主域的子域,可以将Cookie的SameSite设为Lax或Strict,同时配置跨域凭证共享,这样Cookie会被视为第一方Cookie,不会触发第三方拦截规则。

后端配置(Express为例):

  1. 配置CORS允许指定源携带凭证:
const cors = require('cors');
app.use(cors({
  origin: 'https://example.com', // 只允许前端域名跨域请求
  credentials: true // 允许携带Cookie
}));
  1. 调整会话Cookie设置:
app.use(session({
  store: new RedisStore({ client: redisClient }),
  secret: '你的会话密钥',
  resave: false,
  saveUninitialized: false,
  cookie: {
    secure: true,
    sameSite: 'lax', // 或'strict',Lax兼容性更好
    domain: '.example.com', // 设置主域,让子域共享Cookie
    maxAge: 24 * 60 * 60 * 1000
  }
}));

前端请求配置:

用fetch或axios请求时,必须携带凭证:

// Fetch示例
fetch('https://api.example.com/auth/verify', {
  credentials: 'include'
});

// Axios示例
axios.get('https://api.example.com/auth/verify', {
  withCredentials: true
});

这个方案兼容性最好,是跨子域认证的常规做法,完全避开第三方Cookie限制。

方案三:切换到Token-based认证(JWT)

放弃Cookie会话,改用JWT令牌。前端登录后获取JWT,每次请求后端时在请求头里携带令牌,后端用Passport.js的JWT策略验证身份,完全不依赖Cookie,自然不受第三方Cookie规则影响。

后端配置(Passport JWT):

const passportJWT = require('passport-jwt');
const JwtStrategy = passportJWT.Strategy;
const ExtractJwt = passportJWT.ExtractJwt;

const opts = {
  jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), // 从请求头提取令牌
  secretOrKey: '你的JWT密钥'
};

// 定义JWT验证策略
passport.use(new JwtStrategy(opts, (jwtPayload, done) => {
  // 根据JWT中的用户ID查询数据库
  User.findById(jwtPayload.id, (err, user) => {
    if (err) return done(err, false);
    if (user) return done(null, user);
    return done(null, false);
  });
}));

前端处理:

登录成功后存储Token,后续请求携带:

// 登录请求
fetch('https://api.example.com/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ username: 'xxx', password: 'xxx' })
})
.then(res => res.json())
.then(data => {
  localStorage.setItem('authToken', data.token); // 存储Token
});

// 后续请求
const token = localStorage.getItem('authToken');
fetch('https://api.example.com/protected', {
  headers: {
    'Authorization': `Bearer ${token}`
  }
});

注意:JWT要处理过期问题,可搭配Refresh Token使用;存储Token时要注意XSS风险,建议把Refresh Token存在HttpOnly Cookie里,Access Token存在内存中。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 12:22:38