Cannot set cookies correctly

Sorry that I am new to backend. Please correct me for anything I get wrong.

I originally put the jwt refresh token in local storage, but after I done some research, I think it may be better to put it in the cookies.

So now I would like to store refresh token in cookies. Thus I added the “response.cookie” line to my login function.

 // ... user data get here ...

 let token
 try {
     token = await auth.withRefreshToken().attempt(email, password) 
     console.log('token: '+JSON.stringify(token))
 } catch (e) {
     console.log(e)
     return response.status(401).send({ message:'Incorrect password' })
 }

Object.assign(user, token)
console.log('cookies: '+token.refreshToken)
response.cookie('refresh_token', token.refreshToken, {httpOnly: true})
return response.json(user)

Then I tried to call in postman. I get everything alright in the console log. I also get the user data returned correctly.

Problem 1:
However, when I checked the cookies tab, the “refresh_token” cookie is not the same as the refresh token I get.
e.g. Within the same call, I get a refresh token “e2a2ef00221e63895189469fac1f53d8Picrp10ArCzESVg0ySv7UMR/IuH+3mupEEgBfjHD48UJtsGz8Mj/BleK4SMhwIuz” generated ;
but in “refresh_token” cookies it is “22bda52b9fa72efcbfe90d69604501afV9bfpTNsWoxdnZKqDD8hIURx1FmcglVYA8N5OE7mNLMMclfxtaBa%2B85mVGIDwwLmR5tO%2Fw1RPf4EWqeOqbcarsXFu%2BOSsUHHYZ%2BI5Jxj4SpovyhuknIyfQoxHyg7%2BZPqJskJ3yIZHpjWaLx2IFEvWbQuI2VEaGQ7ZVkU5ALAP2OMIHRGIsUjJ9MO1fplPMzsW2SZ7pPQ%2FVBtmgVaYACpvA%3D%3D”.
(and I have checked that it is also not the same as the decrypted token in database)
So where does the code in cookies come from? How can I fix it?

Problem 2:
If I try to call the api in Chrome, I cannot even get any cookies. (I see nothing under “Cookies” in the “Application” tab in the inspector.)
Do I need to get the cookies in the frontend manually? I am using Reactjs as my frontend app. But since the cookie is set to httpOnly, so shouldn’t it be set automatically after the api is called? What should I do?

Can anyone help me? Thank you.

1 Like

Hi @windy0108 :wave:

Problem 1 :

The response.cookie() method encrypt the cookie.

If you want to get plain token, you need to use response.plainCookie()

Problem 2 :

Your react app and adonis app are on the same domain?

1 Like

Hello, thank you for your reply.

For Problem 1: I see… I’ve tried and it works. Thanks!

And for Problem 2:
My react app is on localhost:3000 and adonis app is on localhost:3333.
So it needs to be on same port?
I tried to add a line “proxy”: “http://localhost:3333 in package.json in React app as stated in the solution here.
It seems that not working as I can’t the cookies though.

I also tried to see if the proxy is working, so after adding proxy I set the ‘origin’ in cors.js to false in Adonis. Then when I send api I get this error:

Access to XMLHttpRequest at 'http://127.0.0.1:3333/login' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header contains the invalid value 'false'.
xhr.js:178 POST http://127.0.0.1:3333/login net::ERR_FAILED

I don’t know if I test it correctly, but seems it’s not okay?

Sorry for late answer, lot of work :tired_face:

Cors error

add these lines to your cors.js:

...
module.exports = {
  origin: (origin) => {
    // Allow all connection on dev mode
    if (process.env.NODE_ENV === 'development') {
      return true;
    }

    // Production : allow only from your domain
    if (origin.includes('your.domain')) {
      return true;
    }

    return false;
  },
...

It seems that not working as I can’t the cookies though.

What’s your adonis cookie configuration (domain)?

1 Like

Thank you. Nvm we have some timezone difference LOL

What’s your adonis cookie configuration ( domain )?

Sorry are you talking about the session.js in config folder?

cookie: {
    httpOnly: true,
    sameSite: false,
    path: '/'
  },

It was set as default. And I have just tried to set the path to path: 'http://localhost:3000' or add a line domain:'http://localhost:3000' but seems not working.

1 Like

haha yes probably :laughing:

I try your session.js on one of my projects (nuxt) and it works.

If cookies are not setted, I think the problem is in your react app.
Try fix cors error with connect-src : https://content-security-policy.com/connect-src
and tell me if it’s still not working.

1 Like

I am not quite sure if I have done it correctly.
I just tried to add a meta tag in the html file in the React app:

<meta http-equiv="Content-Security-Policy" 
    content="connect-src 'self' http://127.0.0.1:3333/ ">

Seems nothing changed.
And I find that Adonis also get CSP in its shield.js so I also add something like this:

directives: {
      scriptSrc: ['self', 'http://127.0.0.1:3000']
    },

And seems nothing changed.

I try your session.js on one of my projects (nuxt) and it works.

So with the Adonis default setting it should be working?

Btw I am using axios to send api in React app, will there be something related?
And do I need to receive the cookies “manually” in the front end app? Should the httpOnly cookies be set by the response returned or by me?

1 Like

And I find that Adonis also get CSP in its shield.js

Only use this feature when you use adonis for front-end apps (Edge views)

So with the Adonis default setting it should be working?

Yes

Btw I am using axios to send api in React app, will there be something related?

I also use axios without problems

And do I need to receive the cookies “manually” in the front end app?

Nope. It’s automatically set by browser

Can you share you react & adonis project repo? (here or PM). It’s not easy to help you with only question/answer :blush:

Really sorry for the late reply, got distracted by job.
I have just added you to the github repo named dreamyhometown. Sorry if it makes too sudden because I am not quite sure how should I share it to you… :sweat_smile:

1 Like

thx perfect :smile:
I’ll take a look at it :+1: (probably tomorrow - lot of work)

I think I finally found a solution :tada:

Set axios withCredentials to true & configure your adonis cors.js

Cors.js

module.exports = {
  ...
  credentials: true,
  ...
}

your API/api.js:

export const api = axios.create({
  baseURL: "http://127.0.0.1:3333/",
  responseType: "json",
  withCredentials: true
});

Does that solve your problem?

1 Like

Sorry for late reply again and thank you for you help. I have just tidy up a bit and pushed the changes to github.

I have tried to add this before and I just try it again, seems not working. Should I find the cookies in the ‘Cookies’ under ‘Application’ tab in the ‘Inspector’?

If you don’t mind, could you please try to run and see if it works on your side?

  1. click ‘登入’ on the top right corner
  2. enter ‘t@t.com’ as email and ‘Test123456’ as password
  3. click the ‘登入’ button beneath

This is the login method and that should set the cookies in my thought. I have tested the api using Postman and it should work fine, but I can’t see the cookies in my chrome browser.

Sorry for late reply again and thank you for you help. I have just tidy up a bit and pushed the changes to github.

No problem, you’re welcome :slight_smile: . I will check this :+1:

I have tried to add this before and I just try it again, seems not working. Should I find the cookies in the ‘Cookies’ under ‘Application’ tab in the ‘Inspector’?

Yep

This is the login method and that should set the cookies in my thought. I have tested the api using Postman and it should work fine, but I can’t see the cookies in my chrome browser.

Okay, it’s weird :thinking:. I check your new code tomorrow (lot of work now :confounded:)