Home > Enterprise >  Axios doesn't create a cookie even though set-cookie header is there?
Axios doesn't create a cookie even though set-cookie header is there?

Time:05-04

Front-End: [Axios]

  const formSubmit = async (e) => {
    e.preventDefault()
    const formData = new FormData(e.target)
    const email = formData.get('email')
    const password = formData.get('password')
    try {
      const res = await axios.post('http://172.16.2.19:3001/api/v1/auth/login', {
        email,
        password,
      })
      console.log(res.data) // its okay, I can login if email & password are correct.
    } catch (error) {
      console.log(error)
    }
  }

Back-End [Nodejs ExpressJs]:

Inside App.js:

const cors = require('cors')
app.use(cors({ credentials: true }))

Inside Login.js (/auth/login endpoint):

// ... code, then... if email & password are correct:
// 3600000ms = 1hour
res.cookie('jwt', token, { httpOnly: true, expires: new Date(Date.now()   3600000 })
res.status(200).json({
    status: 'success'
    token,
    data: userDoc,
})

Then, when I login in my browser:

enter image description here

I can login successfully, but no cookies will be created, see:

enter image description here

  • The front-end http service (react app) is running on http://172.16.2.19:3000
  • The back-end http service (expressjs) is running on http://172.16.2.19:3001
  • The axios requests I'm sending from the front-end are requesting: http://172.16.2.19:3001

So what's the problem?

The problem that no cookies are getting created in the browser is preventing me from continuing to design the front-end application, because if I wanted to request anything from my API, I have to be authenticated, all the routes on the API I made are protected, so if I wanted to request anything from the API, I will have to send my jwt token along with the request.

edit **:

here's the response from the /auth/login endpoint after successfully logging in:

enter image description here

  • I am using brave browser, the latest version.
  • I tried this on firefox, it has the same behavior.

enter image description here

CodePudding user response:

I would check by passing {withCredentials: true} as the third argument to the axios method to allow the browser to set the cookie via the request.

CodePudding user response:

I don't think it is correct to use the backend to save cookies, as cookies is a browser feature separate from the database. I might be wrong though. When the post is successful, res will return a token. You save this token in the browser's local storage.

const formSubmit = async (e) => {
e.preventDefault()
const formData = new FormData(e.target)
const email = formData.get('email')
const password = formData.get('password')
try {
  const res = await axios.post('http://172.16.2.19:3001/api/v1/auth/login', {
    email,
    password,
  })
  //browsers local storage
  
  localStorage.setItem('access_token',res.data.access);
  localStorage.setItem('refresh_token',res.data.refresh);
  console.log(res.data) // its okay, I can login if email & password are correct.
}

You will then have to create an authorization header as such

headers:{
        Authorization: localStorage.getItem('access_token') 
            ? 'JWT ' localStorage.getItem('access_token')
            : null

    }

CodePudding user response:

GUYS GUYS GUYS I found it!!!! after 3 hours of researching, let me save your time:

For anyone having the same problem, all you have to do is

change your backend code from:

const cors = require('cors')
app.use(cors({ credentials: true }))

to

app.use(cors({ credentials: true, origin: true }))

why?

setting origin property to true is going to reflect the request origin, the origin property can be a string if you wanted to specify a particular domain, ex: http://localhost:3000. But if you have more than one client, setting this to true is a wise choise.

and for those of you wondering about mobile devices in case of specifying a string for the origin field with one particular domain. This problem of cors only happens in browsers, any other client doesn't use that CORS policy.

  • Related