'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.
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);
}
Solution 1:[1]
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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Fer Toasted |

