Reputation: 9285
I am trying to set a cookie which has my auth token in it. I can see it being returned in the response header set-cookie: xxxxxx
but for whatever reason, the browser is not storing the cookie.
On my react front end http://app1.dev:3001
I am making an POST api call as such:
return axios.get(
`${apiUrl}/info`,
{ withCredentials: true }
)
.then(res => res.data)
.catch(console.error)
And I have a simple Koa server running on http://localhost:3000
const Koa = require("koa")
const Router = require("koa-router")
const bodyParser = require("koa-bodyparser")
const cors = require("@koa/cors")
const axios = require("axios")
const env = require("./env")
const KeyGrip = require("keygrip")
const app = new Koa()
const router = new Router()
const port = env("port")
const keyList = ["xxxxxxx",]
app.keys = new KeyGrip(keyList, "sha256")
router.get("/info", ctx => {
console.log('req', ctx.req)
ctx.cookies.set("token", "test_token", { signed: true, httpOnly: true })
ctx.body = { ok: true }
})
const corsOptions = {
origin: ctx => ctx.request.header.origin,
credentials: true
}
app
.use(cors(corsOptions))
.use(bodyParser())
.use(router.routes())
.use(router.allowedMethods())
app.listen(port, () => console.info(`Listening on port ${port}`))
I suspect it is not being set because it is cross domain. when I use http://localhost:3001
for my front end the cookie gets set fine.
Why are the cookies not being set in browser? Any help would be greatly appreciated.
Upvotes: 15
Views: 30873
Reputation: 49
If anyone having the same problem, this might help.
Frontend:
If using axios then add: withCredentials: true
.
For fetch() add: credentials: 'include'.
Backend:
If you're on http://localhost:....
then you could add to your cookie sameSite:'lax'
, just make sure you're not adding Secure
to this cookie while you on http://localhost
because it is only for https
not http
, else your cookie won't be added to the browser.
While in production adding sameSite: 'none'
and Secure
is ok.
I've added some headers too:
res.setHeader('Access-Control-Allow-Credentials', true);
res.setHeader('Access-Control-Allow-Headers','Origin, X-Requested-With, Content-Type, Accept, authorization')
res.setHeader('Content-Type', 'application/json');
res.setHeader('Access-Control-Allow-Origin','http://localhost:3000');
res.setHeader('Access-Control-Allow-METHODS',"GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH");
Also added:
app.use(cors({
origin: 'http://localhost:3000',
credentials: true
}))
Just make sure you're not using '*'
when adding your origin as shown above res.setHeader('Access-Control-Allow-Origin','http://localhost:3000')
and origin: 'http://localhost:3000'
All of the above helped me with my project, I hope it will help someone else too.
Upvotes: 3
Reputation: 1
I got the same problem . If you response headers contain this header "cache-control:"no-cache,no-store" browser wont set cookies, so remove this header from response.
Upvotes: 0
Reputation: 2693
When you use http://localhost:3001
for the frontend, your frontend and backend servers share the same domain (even being on different ports), so you can see the cookie set by a request to your backend server (and so linked to backend server domain).
When you use different domains, you just can't see the cookie as dev tools are attached to a page that belongs to another domain. But the cookie is saved and will be sent back with subsequent requests.
Upvotes: 10