Search code examples
reactjscookiesnext.jsstrapihttponly

HttpOnly cookie not being sent to api


Im using next.js and strapi. I am trying to set a httpOnly cookie between my next js front-end and my strapi app.

The cookie is recieved by the backend however when i try to make a request to the backend - The cookie is not present. However when i use postman the cookie set is present.

Strapi app:

  const t = await ctx.cookies.get('mytest') // prints undefined with next js but works with postman
  console.log(t);
  ctx.cookies.set('mytest', '123', {
    httpOnly: true,
    maxAge: 1000 * 60 * 60 * 24 * 365,
    secure: false,
  })

next.js frontend:

export default function Home(props: any) {

  async function onClick() {
    const options = {
      method: 'GET',
      'Access-Control-Allow-Credentials': true,
      withCredenitals: true
    }
    const test = await fetch('http://localhost:1337/endpoint', options as any)
    const res = await test.json()

  }

  return (
    <div>

      <div onClick={onClick}>
        Make a fetch to the api
      </div>
    </div>
  )
}

Things i have tried:

  1. Setting specific domains where cors is allowed
  2. Moving the api call to a getServerSideProps function
  3. Making the api call from a next.js api route
  4. I have tried to make the request from a normal html file and it still does not work, So i am now assuming that this is not a next js issue as it was all client side anyway. Heres the HTML code that didnt work - Im getting cors errors and then when im not - I still am not getting the cookie show
    const options = {
      method: 'get',
      mode: 'cors', // no-cors, *cors, same-origin
      cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
      credentials: 'include', // include, *same-origin, omit
      withCredentials: true,
      headers: {
        'Content-Type': 'application/json',
        'Access-Control-Allow-Credentials': true,
        "Access-Control-Allow-Origin": "http://127.0.0.1:1337/myapi"
      },
    }

    const req = await fetch('http://127.0.0.1:1337/myapi', options)
    const res = await req.json()
  1. Changed around how the headers were being sent back on the backend
  console.log(t);
  ctx.cookies.set('mytest', '123', {
    httpOnly: true,
    maxAge: 1000 * 60 * 60 * 24 * 365,
    secure: false,
  })
  ctx.response.header = {
    ...ctx.response.header,
    'Access-Control-Allow-Credentials': true,
    'Access-Control-Allow-Origin': ctx.request.headers.origin,
    'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,UPDATE,OPTIONS',
    'Access-Control-Allow-Headers': 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept'
  }

No luck.

Can anyone tell whats going on? I have been searching for hours but nothing seems to work


Solution

  • I eventually fixed this - The issue was infact because the cookies were not being saved into my browser.

    There were two issues:

    1. Credentials were needed as this was a cross origin request and for cookies to be sent i had to explicitly say so
    credentials: 'include',
    
    1. On the server, I had to state where the origin would come from
    ctx.set('Access-Control-Allow-Origin', ctx.request.headers.origin)
    

    Hope this helps and you dont spend 8 hours randomly console logging stuff