Window.open blocked frame from accessing cross-origin frame

61 views Asked by At

I want users to authenticate their discord account with my application, but I am unable to extract the code in the Authorization process. Discord uses OAuth2. I open a window and call discord's authorization URL which will provides the user with discord's authorization UI. When the user presses Authorize then the redirect URL will be reached and a code is attached to the redirect URL which is used to get the access_token.

Using Angular v16

Discord OAuth2 docs:

https://discord.com/developers/docs/topics/oauth2

The code:

private openWinDiscord = (clientId: string, redirect: string) => new Promise<string>((resolve, reject) => {
        const scopes = 'identify+email';    // scopes seperated by +
        const redirect2 = 'my_redirect_URL';    // Todo: delete this and put redirect in the calling method

        try {
            this.loading = true;
            const endPoint = `https://discord.com/api/oauth2/authorize?client_id=${clientId}&response_type=code&redirect_uri=${redirect2}&scope=${scopes}`; // todo: add '&prompt=none' at the end
            const strWindowFeatures = 'location=yes,height=620,width=520,scrollbars=no,resizable=no,status=yes';
            const discordWindow = window.open(endPoint,
                'discordLoginNav',
                strWindowFeatures
            );

            const closeWindow = () => {
                this.loading = false;
                discordWindow.close();
            };

            const discordIntervalHash = setInterval(() => {
                try {
                    const response_code = discordWindow['location'].hash;
                    if (response_code) {
                        const code = response_code.match(/\#(?:code)\=([\S\s]*?)\&/)[1];
                        if (code) {
                            clearInterval(discordIntervalHash);
                            closeWindow();
                            resolve(code);
                        }

                    } else {
                        if (discordWindow['location']['href'].includes('error')) {
                            clearInterval(discordIntervalHash);
                            closeWindow();
                            reject({
                                message: 'Connection error'
                            });
                        }
                    }
                } catch (e) {
                    console.log('Error parsing query and extracting token', e);
                    this.loading = false;
                    return null;
                }
            }, 1200);

        } catch (e) {
            console.log('Error', e);
            this.loading = false;
            reject('Error');
        }
    })

The Problem:

The authorization UI appears correctly in the window and the user's code in the url is returned correctly with the returnURL, but I am unable to read the URL of the window. When trying to read the URL using const response_code = discordWindow['location'].hash; I get the following error:

Failed to read a named property 'hash' from 'Location': Blocked a frame with origin "http://localhost:4200" from accessing a cross-origin frame.

Is there a way to around cross-origin when using window.open() or is there another route I can follow to Authorize a user in discord?

1

There are 1 answers

0
Franco On

You can add multiple redirect URLs in discord Developer portal. So I added one for localhost that redirects to the same page. Then in my interval the code will be read as soon as the redirect is hit, since cross-origin won't be an issue anymore since the redirect URL in the opened window shared the same domain as my main window.