本地主机:提供的postMessage目标原点与收件人窗口的原点不匹配

时间:2019-10-04 18:49:21

标签: javascript html node.js reactjs

所以我正在尝试构建一个使用sso验证用户身份的应用程序。这是工作流程:

  • 在localhost:3000上启动应用程序(我正在使用单个Web反应 应用程序)
  • 将显示一个弹出窗口(实际上该弹出窗口将调用我的节点js身份验证路由localhost:4000 / authenticate,它将用户重定向到sso身份验证页面)
  • 身份验证后,sso服务器会将用户重定向到节点回调路由(http://localhost:4000/authenticate/callback
  • 节点检查这是否是有效用户并返回成功消息(实际上,节点将发送html + javascript代码以关闭弹出窗口)。
  • 如果收到的消息成功,我们将让用户加载应用

这是一些代码:

App.js

 handleLogIn() {
    const msg = loginTab('http://localhost:4000/authenticate');
    msg.then(response => {
      console.log(response)
    });
  }

  render() {


    let loginButton = (<button onClick={this.handleLogIn.bind(this)}>Sign in</button>)

    return (
      <div>
        {loginButton}
      </div>
    )
  }

loginTab.js

const loginTab = (myUrl) => {
  const windowArea = {
    width: Math.floor(window.outerWidth * 0.8),
    height: Math.floor(window.outerHeight * 0.5),
  };

  if (windowArea.width < 1000) { windowArea.width = 1000; }
  if (windowArea.height < 630) { windowArea.height = 630; }
  windowArea.left = Math.floor(window.screenX + ((window.outerWidth - windowArea.width) / 2));
  windowArea.top = Math.floor(window.screenY + ((window.outerHeight - windowArea.height) / 8));

  const sep = (myUrl.indexOf('?') !== -1) ? '&' : '?';
  const url = `${myUrl}${sep}`;
  const windowOpts = `toolbar=0,scrollbars=1,status=1,resizable=1,location=1,menuBar=0,
    width=${windowArea.width},height=${windowArea.height},
    left=${windowArea.left},top=${windowArea.top}`;

  const authWindow = window.open(url, '_blank', windowOpts);
  // Create IE + others compatible event handler
  const eventMethod = window.addEventListener ? 'addEventListener' : 'attachEvent';
  const eventer = window[eventMethod];
  const messageEvent = eventMethod === 'attachEvent' ? 'onmessage' : 'message';

  // Listen to message from child window
  const authPromise = new Promise((resolve, reject) => {
    eventer(messageEvent, (msg) => {
      if (!~msg.origin.indexOf(`${window.location.protocol}//${window.location.host}`)) {
        authWindow.close();
        reject('Not allowed');
      }

      if (msg.data.payload) {
        try {
          resolve(JSON.parse(msg.data.payload));
        }
        catch(e) {
          resolve(msg.data.payload);
        }
        finally {
          authWindow.close();
        }
      } else {
        authWindow.close();
        reject('Unauthorised');
      }
    }, false);
  });

  return authPromise;
};

export default loginTab;

这是节点响应:

Authentication.js

router.post(process.env.SAML_CALLBACK_PATH,
    function (req, res, next) {
        winston.debug('/Start authenticate callback ');
        next();
    },
    passport.authenticate('samlStrategy'),
    function (req, res, next) {

        winston.debug('Gsuite user successfully authenticated , email : %s', req.user.email)
        return res.sendFile(path.join(__dirname + '/success.html'));

    }
);

success.html

<!doctype html>
<html lang="fr">
<head>
  <title>Login successful</title>
</head>
<body>
  <h1>Success</h1>
  <p>You are authenticated...</p>
</body>
<script>
  document.body.onload = function() {

    console.log( window.opener.location)
    window.opener.postMessage(
      {
        status: 'success'
      },
      window.opener.location
    );
  };
</script>
</html>

问题在于,由于此错误,身份验证后我无法关闭弹出窗口:

无法在“ DOMWindow”上执行“ postMessage”:提供的目标原点('http://localhost:4000')与收件人窗口的原点('http://localhost:3000')不匹配。

我试图将success.html中的window.opener.location更改为'localhost:3000',它可以正常工作,但对于生产环境而言不是一个好主意。

1 个答案:

答案 0 :(得分:1)

好吧,我尝试了很多事情,并使用此技术解决了我的问题。 在开发环境中,我用一颗星星让它正常工作(这不是一个好习惯)。

def search_in_txt(self):
    txt_to_search = self.lineEdit.text()
    try:
        result = self.plainTextEdit_2.find(txt_to_search)

        if result == False:
            # move cursor to the beginning and restart search
            self.plainTextEdit_2.textCursor.movePosition(QTextCursor_MoveOperation=Start)
            self.plainTextEdit_2.find(txt_to_search)
    except:
        self.statusbar.showMessage("This is the last iteration founded")
    return

在生产中,我使用的是真实域名,而不是像这样的localhost:

Expr:  BinOp | Name | Constant ;
Name: id=ID ;
Constant: value=INT ;
BinOp: left=expr op=operator right=expr ;
Operator: Add | Sub ;
Add: 'plus' ;
Sub: 'minus' ;

希望这会对某人有所帮助。

相关问题