Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Express React cookie issues

So here I am building an application based on NodeJS with express4 as the backend and a React frontend. The backend currently allows a user to log in and create an event. This functionality was tested using Postman and works just fine.

Now in the frontend my backend tells me I am unauthorized. Funnily enough when I use a chrome extension to replace the stored cookie (in the browser for the frontend) by the cookie from Postman it suddenly works. So somehow something with cookies must be going wrong.

//Session used in express
app.use(session({
  resave: true,
  saveUninitialized: true,
  secret: process.env.SESSION_SECRET,
  store: new MongoStore({
    url: process.env.MONGODB_URI || process.env.MONGOLAB_URI,
    autoReconnect: true
  }),
  name: 'UsE'
}))

The frontend then uses a fetch polyfill to make the login request.

export const loginAction = (email, password) => {
  return dispatch => {
    dispatch(startLoginFetching())
    return fetch(baseURL + '/api/login', {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                email,
                password
            })

    }).then(response => {
        if(response.ok) {
            dispatch(loginUser())
            dispatch(push('/home'))
        }

        //Read the JSON stream and return it's promise.
        return response.json()
    }).then(json => {
        if(json.msg) {
            dispatch(displayToast(json.msg))
        }
        if(json.user) {
            dispatch(updateUser(json.user))
        }
        dispatch(endLoginFetching())

    })
  }
}

Then the backend uses pasport to authenticate the user and everything should be fine. I am totally at a loss as to what could be the issue here.

Here is the code making a request to the backend that gets a 401 back.

export const createEvent = (infos) => (dispatch) => {
  dispatch(startFetching('createEvent'))
  return fetch(baseURL +'/api/event', {
        method: 'POST',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        },
        credentials: 'include',
        body: JSON.stringify(infos)
    })
    .then(response => response.json())
    .then(json => {
        if (json.msg) {
            dispatch(displayToast(json.msg))
        }
        if(json.event) {
            dispatch(addEvent(json.event))
            dispatch(push(`/event/${json.event._id}`))
        }
        dispatch(endFetching('createEvent'))
    })
}
like image 317
H_end-rik Avatar asked Mar 08 '26 11:03

H_end-rik


1 Answers

By default the fetch polyfill does not pass along cookies to the server. To send cookies with requests made to the same origin, you need to include credentials: 'same-origin' in the options you're passing to fetch().

Your updated code should look like this:

fetch(baseURL + '/api/login', {
          method: 'POST',
          credentials: 'same-origin',
          headers: {
              'Accept': 'application/json',
              'Content-Type': 'application/json'
          },
          body: JSON.stringify({
              email,
              password
          })

}).then(response => { // ...
like image 130
Chris Callahan Avatar answered Mar 11 '26 01:03

Chris Callahan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!