Fer Toasted
Fer Toasted

Reputation: 1738

NextJS: Can't get client side cookies without refreshing

When user logs in, I set the cookies with js-cookie for client side access.

The cookie must be -I think- client accessible since I use Redux Toolkit for async thunk requests.

export async function apiLogin({ email, password }) {
  const data = JSON.stringify({
    email,
    password,
  });

  const config = {
    method: 'post',
    url: `${process.env.API_URL}/auth/login`,
    headers: {
      'Content-Type': 'application/json',
    },
    data,
  };

  const response = await axios(config);

  if (response.status === 200 && response.data) {
    const encodedUser = Buffer.from(JSON.stringify(response.data.user)).toString('base64');

    Cookies.set('token', response.data.token, { expires: 1 });
    Cookies.set('user', encodedUser, { expires: 1 });
    return { user: response.data.user, token: response.data.token };
  }
  if (response.status === 401) {
    return { error: 'User/pw incorrect' };
  }
  return { error: 'Error' };
} 

Those cookies are correctly set upon login - I can see them in the application tab in Dev Tools.

enter image description here

However, those cookies are not accessible to my future requests:

import Cookies from 'js-cookie';

const cookieToken = Cookies.get('token') // this is throws null unless I refresh

export const axiosInstance = (token = cookieToken) => axios.create({
  baseURL: process.env.API_URL,
  headers: {
    Accept: 'application/json',
    Authorization: `Bearer ${token}`,
  },
});

Example request:

  browse(params = {}, hook = null) {
    return axiosInstance()
      .get(endpoint, { params })
      .then((response) => {
        const { data } = response;
        if (hook) {
          data.items = data.items.map((item) => hook(item));
        }
        return data;
      })
      .catch((error) => console.error('error', error));
  },

The cookie getter methods work fine, but only If I refresh the page. So I don't think that's the issue.

EDIT: Is not an axios issue, I did the same with the native fetch API and still couldn't get the cookies. I also tried saving the token in localStorage with the same result.

EDIT2:

I forgot to mention that I have a _middleware.js file that adds protection to routes only if the token is present, and this works fine, so I guess that server side the token is accessible:

export function middleware(req) {
  const userSession = req.headers.get('cookie');
  const url = req.nextUrl.clone();

  if (userSession?.includes('token')) {
    console.log(userSession); // token is there!
    if (req.nextUrl.pathname === '/login') {
      url.pathname = '/';

      return NextResponse.redirect(url);
    }
    return NextResponse.next();
  }

  url.pathname = '/login';
  return NextResponse.rewrite(url);
}

Upvotes: 3

Views: 5612

Answers (1)

Fer Toasted
Fer Toasted

Reputation: 1738

Ok it feel kind of embarassed to have lost so much time fixing this, but apparently setting a cookie token with a name of token was not working, after trying several other methods, it looks like that simply naming it cookieToken did the work. Lmao.

Upvotes: 2

Related Questions