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

Nest.js+Passport会话认证问题:浏览器未携带Session Cookie

Nest.js + Passport 会话认证:浏览器未携带Session Cookie导致403

我用Nest.js结合Passport实现用户会话认证,遇到以下问题:
调用/login接口时,Postman和浏览器均能接收Set-Cookie响应头,但后续请求受保护路由时,Postman可正常携带Cookie通过认证,浏览器却未携带该Cookie,服务器返回403 Forbidden。服务器端打印的session信息在浏览器和Postman中一致,但AuthenticatedGuard在Postman请求中返回true,浏览器请求返回false。


相关代码

main.ts(Nest.js后端配置)

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.use(cookieParser());

  // session配置
  app.use(
    session({
      secret: 'keyboard',
      resave: false,
      saveUninitialized: false,
      cookie: {
        maxAge: 10 * 60 * 1000,
        httpOnly: true,
        sameSite: 'none',
      },
    }),
  );

  app.use(passport.initialize());
  app.use(passport.session());

  app.use((req, res, next) => {
    res.header('Access-Control-Expose-Headers', 'x-total-count');
    next();
  });
  app.enableCors({
    origin: ['http://127.0.0.1:3000','http://localhost:3000/'],
    credentials: true,
  });
  await app.listen(3000);
}
bootstrap();

AuthenticatedGuard(认证守卫)

@Injectable()
export class AuthenticatedGuard implements CanActivate {
  async canActivate(context: ExecutionContext) {
    const request = context.switchToHttp().getRequest();
    console.log(request.session);
    return request.isAuthenticated();
  }
}

受保护路由

@UseGuards(AuthenticatedGuard)
@Patch('edit/:id')
edit(
  @Param('id') id: string,
  @Body() editedData: EditAgentDto,
  @Request() req,
) {
  console.log(editedData)
  if (id === req.user.id) {
    return this.agentService.editAgent(id, editedData);
  }
}

登录守卫与接口

@Injectable()
export class LocalAgentGuard extends AuthGuard('agent') {
  async canActivate(context: ExecutionContext) {
    const result = (await super.canActivate(context)) as boolean;
    const request = context.switchToHttp().getRequest();
    await super.logIn(request);
    return result;
  }
}
@UseGuards(LocalAgentGuard)
@Post('login')
login(@Request() req) {
  return req.user;
} 

前端Axios请求代码(dashboard.tsx)

const onSubmit = (data) => {
  return new Promise((resolve, reject) => {
    axios.patch(`http://localhost:3000/agents/edit/64bcc86e51ce7016ffb3d6c8`,data,{withCredentials: true})
    .then((res) =>{
      toast.success('your data has been saved')
      console.log(res)
      resolve();
    })
    .catch(() => {
      toast.error('something went wrong')
      console.log('error')
      reject()
    });
  })
}

前端Vite配置

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  server:{
    host:'localhost',
    port:3000,
  },
  plugins: [react()],
})

排查与修复方案

1. Cookie的SameSite与Secure配置问题

当sameSite: 'none'时,现代浏览器要求Cookie必须设置secure: true(仅在HTTPS环境下生效)。但你当前是开发环境(HTTP),设置SameSite=None会导致浏览器拒绝存储Cookie。

修改session的cookie配置,根据环境动态调整:

cookie: {
  maxAge: 10 * 60 * 1000,
  httpOnly: true,
  // 开发环境用lax/strict,生产HTTPS环境再用none+secure
  sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax',
  secure: process.env.NODE_ENV === 'production',
},

2. CORS Origin配置错误

你的CORS origin里http://localhost:3000/末尾多了斜杠,和前端实际的http://localhost:3000不匹配,浏览器会因origin不匹配拒绝携带Cookie。去掉斜杠:

app.enableCors({
  origin: ['http://127.0.0.1:3000','http://localhost:3000'],
  credentials: true,
});

3. 前端登录请求未携带withCredentials

登录请求也需要添加withCredentials: true,否则浏览器不会保存登录时的Set-Cookie:

// 示例登录请求
axios.post('http://localhost:3000/login', {username: 'xxx', password: 'xxx'}, { withCredentials: true })

4. 前后端端口冲突

你的前端Vite和后端Nest.js都监听3000端口,会导致端口抢占,实际只有一个服务能运行,引发跨域问题。修改前端端口为5173(Vite默认),并更新CORS origin:

  • Vite配置修改:
export default defineConfig({
  server:{
    host:'localhost',
    port:5173,
  },
  plugins: [react()],
})
  • 后端CORS origin添加http://localhost:5173:
app.enableCors({
  origin: ['http://127.0.0.1:3000','http://localhost:3000', 'http://localhost:5173'],
  credentials: true,
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 04:34:51