I've got a function that creates a cookie (I'm using sveltekit):
src\routes\api\auth\+server.js:
import {login} from "../../../api/auth.js";
import {loginDTO} from "../../../business/data-transfer-objects/login.js";
import {emptyObject} from "../../../helpers/index.js";
import {errorResponse, successResponse} from "../../../core/response.js";
import {AUTH_TOKEN_KEY} from "../../../core/consts.js";
/**
* User Login -> if 200 returned from the server then save the returned token
* into a cookie.
* @param event
* @returns {Promise<Response>}
* @constructor
*/
export async function POST(event) {
const data = await event.request.json();
// validate and create DTO.
const loginData = loginDTO(data);
// if errors returned from building the DTO (validation errors) then return the object.
if (loginData?.errors && !emptyObject(loginData.errors)) {
return errorResponse(data, loginData.errors, 422)
}
// perform login.
const response = await login(loginData);
// if login is not successful then return error.
if (response.status !== 200) {
// remove password from data.
delete data["password"];
return errorResponse(data, response, response.status);
}
// if login is successful then set the auth cookie.
event.cookies.set(AUTH_TOKEN_KEY, response.data.token, {
// send cookie for every page
path: '/',
// server side only cookie so you can't use `document.cookie`
httpOnly: false,
// only requests from same site can send cookies
// https://developer.mozilla.org/en-US/docs/Glossary/CSRF
sameSite: 'strict',
// only sent over HTTPS in production
secure: process.env.NODE_ENV === 'production',
// set cookie to expire after a month
maxAge: 60 * 60 * 24 * 30,
})
return successResponse(response.data, 200);
}
this is called from an actions function when my login form is submitted:
import { redirect } from "@sveltejs/kit";
/** @type {import('./$types').Actions} */
export const actions = {
default: async ({request, fetch}) => {
const data = Object.fromEntries(await request.formData());
const res = await fetch('api/auth', {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify(data)
});
const response = await res.json()
// todo CV-127: once dashboard page is implemented that's the place where this action shall be redirected to.
if (response.status == 200) {
throw redirect(302, '/')
}
return response;
}
}
the cookie is successfully created (see image):
championship-access-token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlYXQiOiIyMDIzLTA1LTIyVDAxOjI4OjMwLjk0MzAwMTE3MloiLCJpYXQiOjE2ODQ3MTY5MTAsImlkIjo3fQ.VaVfzgnib0DhzRO8jUJ-X_2BRIiAGXIq8eEQOs85anI localhost / 6/20/2023, 8:55:10 PM 192 B ✓ Strict
Now, I've created an axios interceptor since I want to retrieve the token stored in the cookie and attach it to my requests. The problem is that I cannot access the cookie. I'm using js-cookie, and the interceptor looks like this:
import axios from "axios";
import Cookies from 'js-cookie';
export const app = axios.create({
baseURL: "http://127.0.0.1:8080/api/v1",
timeout: 1000,
params: {},
});
app.interceptors.request.use(
config => {
console.log("interceptor -> retrieving cookie:");
Cookies.set("test123", "asdasdasd")
console.log(Cookies.get(AUTH_TOKEN_KEY));
console.log("test cookie: ", Cookies.get("test123"))
console.log("cookie: ", Cookies.get(AUTH_TOKEN_KEY));
console.log("ALL COOKIES", Cookies.get())
config.headers['Content-Type'] = 'application/json';
return config;
},
error => {
Promise.reject(error)
}
);
In the code above I'm not trying yet to attach the value of the cookie, I'm simply trying to retrieve it at the moment but it's always undefined. I tried to create a new cookie using js-cookie but doesn't seem to work. Notice that the original cookie was created using a cookie helper from Sveltkit which I cannot access at this point (or at least I don't know how since it's only accessible from server side files), reason why I decided to use js-cookie.
Any idea what's going on? Perhaps is the import the one that I got wrong? I already tried:
import * as Cookies from 'js-cookie' yet the result is the same.
One more thing which I don't know if it's relevant to the question: notice this param used to create the cookie:
httpOnly: false,
even though it is set to false, the cookie is set as httpOnly (see screenshot).
Thanks

First of all try to add
withCredentials: true,toaxios.createoptions:By adding
withCredentials: trueto theaxios.createoptions, Axios will include the cookie header in cross-origin requests, allowing the server to read and set cookies.Regarding the cookie creation: you need to ensure that the interceptor is executed after the cookie is set. Interceptors are executed for every request, so if the cookie is set after the interceptor is called, it won't be available in the interceptor's context.
You can try the following modified interceptor code to troubleshoot the issue:
By introducing a small delay using
setTimeout, you allow some time for the cookie to be set before retrieving it. This delay can help ensure that the interceptor runs after the cookie has been set.Regarding the
httpOnlyflag, setting it to false in your code doesn't guarantee that the cookie won't be treated ashttpOnly. ThehttpOnlyflag is a security measure that prevents client-side JavaScript from accessing the cookie. It is typically enforced by the server, and if the server sets thehttpOnlyflag to true, the client-side code won't be able to access the cookie.