在单页webapp中第二次初始化Okta Signin Widget会引发异常

问题描述 投票:4回答:2

我们正在将Okta Sign-in Widget集成到基于React的webapp中。

The example snippet

var oktaSignIn = new OktaSignIn({baseUrl: baseUrl});
oktaSignIn.renderEl(...)

在第一次渲染窗口小部件时,我们可以正常工作,但在用户登录并再次注销后,webapp再次呈现登录组件并尝试再次执行renderEl以呈现窗口小部件。这会导致抛出以下异常:

Backbone.history has already been started

我创建了this jsfiddle来演示这个问题。它只是实例化一个登录小部件两次(等待后第二次)。您可以看到第二次调用导致抛出异常。

https://jsfiddle.net/nudwcroo/6/

目前,我的解决方法是在转到登录组件时重新加载整个webapp,但这对于单个页面应用程序来说是不合需要的。

这是一个已知的问题?有没有办法在单个javascript会话中初始化登录窗口小部件两次?

javascript okta
2个回答
0
投票

由于窗口小部件每页只能实例化一次,因此最好隐藏/显示所有单页应用程序的元素。

<div id="okta-login-container"></div>

<script type="text/javascript">
    var oktaSignIn = new OktaSignIn(/* config */);

    oktaSignIn.renderEl(
      { el: '#okta-login-container' },
      function (res) {
        if (res.status === 'SUCCESS') {
            // Hide element 
            $("#okta-login-container").hide();
        }
      }
    );
</script>

当您创建logout()函数时,请确保show()元素而不是再次渲染它。

function logout() {
    $('#okta-login-container').show();
    // Do more logic
}

0
投票

对于那些在遵循此处提供的Okta示例后遇到类似问题的人:(https://github.com/okta/samples-js-react/blob/master/custom-login/src/Login.jsx

问题是尝试在单个页面应用程序中多次初始化窗口小部件。我通过仅在App级别初始化窗口小部件,然后在子组件安装/卸载时渲染它并从DOM中删除它来修复此问题。

例:

//App.js
class App extends Component {
  constructor() {
    super()
    this.signIn = new OktaSignIn({...})
  }

  render() {
    return <SignInPage widget={this.signIn} />
  }
}

--

//SignInPage.js
...
  componentDidMount() {
    let { redirectUri } = this.state
    let { widget } = this.props
    widget.renderEl(
      { el: '#sign-in-widget' },
      (response) => {
        response.session.setCookieAndRedirect(redirectUri)
      },
      (error) => {
        throw error;
      },
    );

  }

  componentWillUnmount() {
      let { widget } = this.props
      widget.remove()
  }

  render() {
    return  <div id="sign-in-widget"/></div>
  }
© www.soinside.com 2019 - 2024. All rights reserved.