简体   繁体   中英

Cannot set cookie with Nest.js

I have created /sign-in endpoint that basically returns object with 2 tokens - refresh token and access token.

@Post('/sign-in')
signIn(@Body() signInUserDto: SignInUserDto): Promise<TokensDto> {
  return this.userService.signIn(signInUserDto);
}

What I want to do, is to send access token normally as JSON , but send access token as cookie, so I changed a little bit this function and made it look like this.

@Post('/sign-in')
async signIn(
  @Request() req: ExpressRequest,
  @Response() res: ExpressResponse
): Promise<ExpressResponse<any, Record<string, any>>> {
  const { _at, _rt } = await this.userService.signIn(req.body);
  res.cookie('_rt', _rt, {
    httpOnly: true,
    sameSite: 'strict',
    maxAge: 7 * 24 * 60 * 60 * 1000
  });
  return res.status(200).json({ _at });
}

As a result, I get access token in response, but I don't get refresh token in cookie. Right away I can tell, that on front-end I have withCredentials: true in axios. Also, when I send request to this endpoint with postman, I get cookie, but not on front-end. Why it happens and how I can make it set cookie?

PS.

In server terminal, no matter how I send request, from front-end or postman, I get this warning:

Error [ERR_INTERNAL_ASSERTION]: This is caused by either a bug in Node.js or incorrect usage of Node.js internals.
Please open an issue with this stack trace at https://github.com/nodejs/node/issues

    at assert (internal/assert.js:14:11)
    at ServerResponse.detachSocket (_http_server.js:223:3)
    at resOnFinish (_http_server.js:685:7)
    at ServerResponse.emit (events.js:314:20)
    at onFinish (_http_outgoing.js:735:10)
    at onCorkedFinish (_stream_writable.js:673:5)
    at afterWrite (_stream_writable.js:490:5)
    at afterWriteTick (_stream_writable.js:477:10)
    at processTicksAndRejections (internal/process/task_queues.js:83:21)

I was able to solve this problem, but only partly.

The problem was with front-end, not back-end, because, as I said before, I was able, using postman, to get cookie from server.

And here is the issue.

First of all, you need to install 2 packages cookie and @types/cookie , than, in route (as we remember, routing in Next.js works as folder structure in project), you need to import serialize from installed package:

import { NextApiRequest, NextApiResponse } from "next";
import { AxiosError } from "axios";
import { api } from "../../../api";
import { serialize } from 'cookie'

export default async (
  req: NextApiRequest,
  res: NextApiResponse
) => {
  try {
    const { data } = await api.post('/user/sign-in', req.body)

    res.setHeader('Set-Cookie', serialize('_rt', data.data._rt, {
      httpOnly: true,
      sameSite: 'strict',
      maxAge: 7 * 24 * 60 * 60 * 1000
    }))
    return res.json(data)
  } catch (error) {
    return res
      .status((error as AxiosError).response?.status as number)
      .json((error as AxiosError).response?.data);
  }
}

And as a result, in response, you can see Set-Cookie header with cookie, but, that's why it resolved partly, I don't see this cookie in devtools in Application/Cookies section.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM