Window.closed =窗口打开时为真[弹出窗口中的Twitter OAuth2]

b5lpy0ml  于 2023-01-08  发布在  其他
关注(0)|答案(1)|浏览(122)

信息

我尝试在弹出窗口中实现 * OAuth with Twitter 同样的实现适用于Google和Discord *,目前我正在做的是,在一个名为openOAuthWindow的函数中我正在创建一个新的窗口弹出与OAuth URL,然后创建一个Promise*并将resolvereject函数保存在window对象中。之后, * 在子窗口中当服务重定向到我的redirect_uri时,我的页面调用父窗口中保存的resolvereject(通过从window.opener引用)取决于OAuth结果并关闭OAuth窗口。关闭子项后I '我正在从父窗口中清除resolvereject函数,并相应地解决或拒绝承诺。此外,我还为setInterval设置了一个间隔,用于检查oAuthWindow.closed === true(指示窗口是否已关闭)。在oAuthWindow.closed === truePromise未满足的情况下,指示用户手动关闭OAuth窗口,并返回OAuthError作为Promise的结果。
∮问题是
正如我前面提到的,Google和Discord都很好,问题出在Twitter上,当Twitter OAuth页面完全加载时,oAuthWindow.closed返回true(当Windows还开着的时候),我的逻辑失败了(因为我抛出的错误表明用户手动关闭了OAuth窗口)。另外,当我转到oAuthWindow中的DevTools时,window.opener属性等于null。2所以我对父窗口的引用也丢失了。
∮真正的问题∮
1.有没有其他方法可以检查Windows是开着还是关着?(我试着找一些解决方法,但找不到)
1.有没有其他的解决方案可以在弹出窗口中实现OAuth?(欢迎提供)
1.也有任何安全缺陷,以避免在弹出窗口中使用OAuth 2?(我已经做了这方面的研究,我已经做了OAuth安全的调查,我发现的唯一安全问题可能是从网站访问子窗口,但该链接是不可能的,由于同源政策

public static async openOAuthWindow(url: string, windowFeatures: string = "width=500,height=600,popup=true"): Promise<CodeAndState> {
    if(!windowFeatures.includes("noopener")) {
        const oAuthWindow: Window = window.open(url, "_blank", windowFeatures)!;

        let fulfilled = false;

        const removePromiseCallbacksAndFullfill = () => {
            delete window.returnAuthCode;
            delete window.returnOAuthError;
            fulfilled = true;
        };

        let resultPromise: Promise<CodeAndState> = new Promise<CodeAndState>((resolve, reject) => {
            window.returnAuthCode = resolve;
            window.returnOAuthError = reject;
        }).then((codeAndState: CodeAndState) => {
            removePromiseCallbacksAndFullfill();
            return codeAndState;
        }).catch((error) => {
            removePromiseCallbacksAndFullfill();
            return Promise.reject(error);
        });

        let windowAliveInterval = setInterval(() => {
            if (oAuthWindow.closed) {
                clearInterval(windowAliveInterval);
                if(!fulfilled) {
                    const error = new OAuthError("User closed the window", ERROR_STATUSES.USER_CLOSED_OAUTH_WINDOW);
                    window.returnOAuthError!(error);
                }
            }
        }, 500);

        return resultPromise;
    }
    throw new Error("OAuth window sends code to the parent window, so it must be opened without 'noopener' feature");
}

感谢您的努力,任何回答/评论都将不胜感激!

ru9i0ody

ru9i0ody1#

我最近也遇到了这个问题,在弹出窗口中打开GoogleOAuth提示被错误地认为是“关闭”。
您可以考虑的一种解决方案是使用broadcast channel:当父窗口打开oauth弹出窗口时,也打开一个广播频道。在Oauth登录后,重定向到一个页面,该页面在弹出窗口关闭之前向父页面发送一条消息。
如果父窗口在广播通道上没有接收到任何消息,则表明登录在成功之前已关闭。

相关问题