如何在 NestJS 中设置 HTTP only cookie
How to set HTTP only cookie in NestJS
我正在尝试使用 accessToken 和 refreshToken 实现 JWT 授权。 accessToken 和 refresh token 都需要在 HTTP only cookie 中设置。
我试过这段代码,但它没有设置 cookie。我这里使用的是 NestJS 框架。
import { Controller, Request, Post, Body, Response } from '@nestjs/common';
@Controller()
export class UserController {
constructor() {}
@Post('users/login')
async login(
@Request() req,
@Body() credentials: { username: string; password: string },
@Response() res,
) {
try {
// Login with username and password
const accessToken = 'something';
const refreshToken = 'something';
const user = { username: credentials.username };
res.cookie('accessToken', accessToken, {
expires: new Date(new Date().getTime() + 30 * 1000),
sameSite: 'strict',
httpOnly: true,
});
return res.send(user);
} catch (error) {
throw error;
}
}
}
res.send() 方法工作正常我正在获取响应数据。我如何在此处设置 cookie?
这是我的 main.ts 文件:-
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { Logger } from '@nestjs/common';
import { AuthenticatedSocketIoAdapter } from './chat/authchat.adapter';
import * as cookieParser from 'cookie-parser';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors();
app.use(cookieParser());
app.useWebSocketAdapter(new AuthenticatedSocketIoAdapter(app));
await app.listen(3000);
Logger.log('User microservice running');
}
bootstrap();
并获取我正在使用的 cookie:-
request.cookies
评论中的对话:
Axios 在客户端需要将 withCredentials
设置为 true
才能将 cookie 发送回服务器。服务器正在按预期发送和设置 cookie。
我遇到了和你几乎一样的问题。 Axios 无法保存 cookie。
设置 SameSite 所需的 Chrome:'none',安全:true。
你仍然没有工作。它确实使用 fetch 方法保存了 cookie,但仅在浏览器 运行 Chromium 中...所以 mozilla 没有收到它。我的 axios 是:
const response = await axios.post(url+'/login', loginState, {withCredentials: true});
后台Nestjs:Main.ts:
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.setGlobalPrefix('v1/api');
app.use(cookieParser());
app.useGlobalPipes(new ValidationPipe());
app.enableCors({
credentials: true,
origin: process.env.FRONTEND_URL,
})
await app.listen(3000);
}
我的AuthService Login函数(记住Res中的passthrought: true)
@Post('login')
async login(
@Body()body: LoginUserDTO,
@Res({passthrough: true}) response: Response
): Promise<any> {
const user = await this.userService.getOne({where: {"user_email": body.email}});
if(!user) {
throw new NotFoundException('User not found')
}
if(!await bcrypt.compare(body.password, user.user_password)) {
throw new BadRequestException('Password incorrect');
}
const frontendDomain = this.configService.get<string>('FRONTEND_DOMAIN');
const jwtToken = await this.jwtService.signAsync({id: user.user_id});
response.cookie('jwt', jwtToken, {httpOnly: true, domain: frontendDomain,});
return {'jwt': jwtToken}
}
奇怪的是,解决我问题的方法是将域添加到 response.cookie。
还有用于 CORS 和 cookie 域的我的开发环境变量:
FRONTEND_URL = http://localhost:3333
FRONTEND_DOMAIN = localhost
希望我的代码能帮到你
我正在尝试使用 accessToken 和 refreshToken 实现 JWT 授权。 accessToken 和 refresh token 都需要在 HTTP only cookie 中设置。
我试过这段代码,但它没有设置 cookie。我这里使用的是 NestJS 框架。
import { Controller, Request, Post, Body, Response } from '@nestjs/common';
@Controller()
export class UserController {
constructor() {}
@Post('users/login')
async login(
@Request() req,
@Body() credentials: { username: string; password: string },
@Response() res,
) {
try {
// Login with username and password
const accessToken = 'something';
const refreshToken = 'something';
const user = { username: credentials.username };
res.cookie('accessToken', accessToken, {
expires: new Date(new Date().getTime() + 30 * 1000),
sameSite: 'strict',
httpOnly: true,
});
return res.send(user);
} catch (error) {
throw error;
}
}
}
res.send() 方法工作正常我正在获取响应数据。我如何在此处设置 cookie?
这是我的 main.ts 文件:-
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { Logger } from '@nestjs/common';
import { AuthenticatedSocketIoAdapter } from './chat/authchat.adapter';
import * as cookieParser from 'cookie-parser';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors();
app.use(cookieParser());
app.useWebSocketAdapter(new AuthenticatedSocketIoAdapter(app));
await app.listen(3000);
Logger.log('User microservice running');
}
bootstrap();
并获取我正在使用的 cookie:-
request.cookies
评论中的对话:
Axios 在客户端需要将 withCredentials
设置为 true
才能将 cookie 发送回服务器。服务器正在按预期发送和设置 cookie。
我遇到了和你几乎一样的问题。 Axios 无法保存 cookie。 设置 SameSite 所需的 Chrome:'none',安全:true。 你仍然没有工作。它确实使用 fetch 方法保存了 cookie,但仅在浏览器 运行 Chromium 中...所以 mozilla 没有收到它。我的 axios 是:
const response = await axios.post(url+'/login', loginState, {withCredentials: true});
后台Nestjs:Main.ts:
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.setGlobalPrefix('v1/api');
app.use(cookieParser());
app.useGlobalPipes(new ValidationPipe());
app.enableCors({
credentials: true,
origin: process.env.FRONTEND_URL,
})
await app.listen(3000);
}
我的AuthService Login函数(记住Res中的passthrought: true)
@Post('login')
async login(
@Body()body: LoginUserDTO,
@Res({passthrough: true}) response: Response
): Promise<any> {
const user = await this.userService.getOne({where: {"user_email": body.email}});
if(!user) {
throw new NotFoundException('User not found')
}
if(!await bcrypt.compare(body.password, user.user_password)) {
throw new BadRequestException('Password incorrect');
}
const frontendDomain = this.configService.get<string>('FRONTEND_DOMAIN');
const jwtToken = await this.jwtService.signAsync({id: user.user_id});
response.cookie('jwt', jwtToken, {httpOnly: true, domain: frontendDomain,});
return {'jwt': jwtToken}
}
奇怪的是,解决我问题的方法是将域添加到 response.cookie。
还有用于 CORS 和 cookie 域的我的开发环境变量:
FRONTEND_URL = http://localhost:3333
FRONTEND_DOMAIN = localhost
希望我的代码能帮到你