I'm implementing login with Spotify. Basically, I open a new window to allow user to log in.
As soon as the window is opened, I get this error in console:
DOMException: Blocked a frame with origin "http://localhost:3000" from accessing a cross-origin frame. at http://localhost:3000/static/js/main.chunk.js:2522:30
This is the handler to open the window, where spotifyLoginUrl
has the following pattern:
https://accounts.spotify.com/en/authorize?scope=user-follow-read%20user-read-email&response_type=code&redirect_uri=http:%2F%2Flocalhost:3000%2F&client_id=x&show_dialog=true&state=y
const handleSpotifyLogin = (event) => {
popupWindow
.open(
spotifyLoginUrl,
'spotify-authorization',
530,
840,
getSpotifyCode,
getSpotifyState
)
.then(({ loginCode, loginState }) => {
...
})
.catch((err) => {
console.error(err);
});
};
And the popup window handler:
export const openWindow = (url, windowName, w, h) => {
const y = window.top.outerHeight / 2 + window.top.screenY - h / 2;
const x = window.top.outerWidth / 2 + window.top.screenX - w / 2;
return window.open(
url,
windowName,
`toolbar=no, location=no, directories=no, status=no, menubar=no,
scrollbars=no, resizable=no, copyhistory=no,
width=${w}, height=${h}, top=${y}, left=${x}`
);
};
class popupWindow {
constructor(url, id, w, h, getLoginCode, getLoginState) {
this.url = url;
this.id = id;
this.w = w;
this.h = h;
this.getLoginCode = getLoginCode;
this.getLoginState = getLoginState;
}
open() {
const { url, id, w, h } = this;
this.window = openWindow(url, id, w, h);
}
close() {
this.cancel();
this.window.close();
}
poll() {
this.promise = new Promise((resolve, reject) => {
this.interval = window.setInterval(() => {
try {
const popup = this.window;
if (!popup || popup.closed) {
this.close();
reject();
return;
}
if (
popup.location.href === this.url ||
popup.location.pathname === 'blank'
) {
return;
}
resolve({
loginCode: this.getLoginCode(popup),
loginState: this.getLoginState(popup),
});
this.close();
} catch (err) {
console.error(err);
}
}, 300);
});
}
cancel() {
if (this.interval) {
window.clearInterval(this.interval);
this.interval = null;
}
}
then(...args) {
return this.promise.then(...args);
}
catch(...args) {
return this.promise.then(...args);
}
static open(...args) {
const popup = new this(...args);
popup.open();
popup.poll();
return popup;
}
}
I use Express in server side, and have enabled CORS and Helmet there:
app.use(cors());
app.use(helmet());
I tried to add accounts.spotify.com
to CSP but still getting the same error:
app.use(
helmet.contentSecurityPolicy({
useDefaults: true,
directives: {
'script-src': ["'self'", 'https://accounts.spotify.com'],
},
})
);
What should I do to fix the error?