functions-samples
functions-samples copied to clipboard
Safari does not include cookies in JSONP requests
How to reproduce these conditions
Sample name or URL where you found the bug
firebase/functions-samples/spotify-auth, but the other auth examples may be affected too.
Failing Function code used (including require/import commands at the top)
spotify-auth/functions/index.js
const functions = require('firebase-functions');
const cookieParser = require('cookie-parser');
[...]
exports.token = functions.https.onRequest((req, res) => {
try {
cookieParser()(req, res, () => {
console.log('Received verification state:', req.cookies.state);
console.log('Received state:', req.query.state);
if (!req.cookies.state) {
throw new Error('State cookie not set or expired. Maybe you took too long to authorize. Please try again.');
} else if (req.cookies.state !== req.query.state) {
throw new Error('State validation failed');
}
[...]
Steps to set up and reproduce
Setup the Spotify-auth example and use Safari (Version 12.0 14606.1.36.1.9) to test it.
Debug output
Errors in the console logs
State cookie not set or expired. Maybe you took too long to authorize. Please try again.
The req.cookies
object is empty.
Expected behavior
No exception.
Actual behavior
As far as I can see, Safari does not include cookies in JSONP request. It works fine in Chrome though.
XHR request do not work neither ☹️ I am now redirecting the whole popup to a firebase function and then passing the token back to the app via window.postMessage()
. Although it works fine I'm not sure wether or not this is the right way to do it 🤔
XHR request do not work neither ☹️ I am now redirecting the whole popup to a firebase function and then passing the token back to the app via
window.postMessage()
. Although it works fine I'm not sure wether or not this is the right way to do it 🤔
Can you share your solution, is it still working for you?
same, looks nobody care this .
I also have this issue but why noone offers a solution or help here?
Same issue, with linked in sample. Can someone post a workaround as it stops PWA working on iOS.
Same problem here in Chrome. I got the error: "Error in the token Function: Error: State cookie not set or expired. Maybe you took too long to authorize. Please try again."
Log: Received verification state: undefined
I think I was finally able to solve this after poking around multiple tickets/PRs.
My solution ended up using code from: #826 #849 #852
The basic rundown:
- Change the
req.cookies.state
to bereq.cookies.__session
across the files as seen in these updated files - Update the
res.cookie
object to be
res.cookie('__session', state.toString(), {
maxAge: 3600000,
secure: true,
httpOnly: true,
SameSite: 'none'
});
(note we changed res.cookies('state'...
to be res.cookies('__session'...
from step 1), also note this comment
- Updated my hosting rewrites to support calling the functions like:
// in firebase.json
"public": "public",
"rewrites": [
{
"source": "/redirect",
"function": "redirect"
},
{
"source": "/token",
"function": "token"
}
]
Note, I don't know if this is the secure/best/optimal way. I attempted each of these on their own and then started combining them to see what worked.
@kevinguebert You're a godsend!