I am setting a secure, http only, same site none cookie on www.domain-a.org express server. Using CORS and CSP I want to fetch that cookie from www.domain-b.com which also uses express. Every time a user lands on domain-b, it will make a fetch request on the server to domain-a to get its cookie.
This is my example code below for testing purposes but it's not working. When I try to fetch domain-a cookie from domain-b I get back an empty object. Are these requests possible?
domain-a.org
With CORS I've set up these policies on my send-cookie route so that domain-b is only allowed to call the endpoint and request the cookie from domain-a:
Access-Control-Allow-Origin: 'https://www.domain-b.com'
Access-Control-Allow-Methods: ['GET','OPTIONS']
Access-Control-Allow-Origin: true
router.get('/set-cookie', (req, res) => {
res.cookie('domain-a-cookie', 'domain-a-value', {
httpOnly: true,
sameSite: 'none',
secure: true,
maxAge: 60 * 60 * 24 * 30
})
res.send('set domain-a cookie')
})
router.get('/send-cookie', cors({ origin: 'https://www.domain-b.com', methods: ['GET','OPTIONS'], credentials: true, preflightContinue: true}), (req, res) => {
const response = {
status: 'success'
}
if (req.cookies && req.cookies['domain-a-cookie']) {
response.data = {
cookie: req.cookies['domain-a-cookie']
}
}
res.status(200).send(response)
})
domain-b.com
router.get('/get-cookie', (req, res) => {
fetch('https://www.domain-a.org/send-cookie', {
method: 'GET',
mode: 'cors',
credentials: 'include'
})
.then(response => {
if (response.ok) {
return response.json()
}
return Promise.reject(response)
})
.then(result => {
if (result.status === 'success' && result.data && result.data.cookie) {
res.cookie('domain-b-cookie', result.data.cookie, {
httpOnly: true,
sameSite: 'none',
secure: true,
maxAge: 60 * 60 * 24 * 30
})
res.status(200).send({ status: 'success' })
} else {
res.status(500).send(result)
}
})
.catch(error => {
res.status(500).send(error)
})
})
If a user logs in to www.domain-a.org, can I share that session and automatically log in that user on www.domain-b.com?
Not with your approach.
This is a very simple view of how cookies work for authentication:
Later the user visits www.domain-b.org. The browser does not send the cookie to www.domain-b.org because it is a different website. It would be a horrible security problem if I logged into my online banking, then I visited your website and my browser sent you my bank's cookies. I don't know you. I certainly don't trust you with my bank account.
Your server side code makes a request to www.domain-a.org. It isn't sending the cookie stored in the browser. It isn't the browser. It doesn't have that cookie. It would be a security nightmare if the browser had handed that cookie over.
A general approach to doing single sign on would be:
http://www.domain-a.org/sso?redirect=http://www.domain-a.org/login
http://www.domain-a.org/sso?redirect=http://www.domain-b.org/login
which provides them with a prompt "Do you want to share your personal data with B?"http://www.domain-b.org/login?token=some-auto-generated-token
Yes. This is relatively complicated. There are a lot of checks. You're dealing with authentication/authorization here. Security is paramount.
The standard for this is OAuth. Password.js has some features for acting as an OAuth client for Node.js.