【问题标题】:In React, how do I retrieve information from the database after Authentication but before Authorization?在 React 中,如何在 Authentication 之后但在 Authorization 之前从数据库中检索信息?
【发布时间】:2020-06-11 15:30:36
【问题描述】:

我正在构建一个链接到 Firebase Auth 的 React 应用。我按照this 教程进行设置。

所以,我现在有一个允许用户登录的应用,通过在提交登录表单时执行以下操作:

onSubmit = event => {
    const { email, password } = this.state;

    this.props.firebase
      .doSignInWithEmailAndPassword(email, password)
      .then(
          this.setState({ ...INITIAL_STATE }),
          this.props.history.push(ROUTES.DASHBOARD)
      )
      .catch(error => {
        this.setState({ error });
      });

  event.preventDefault();
};

仪表板被授权组件包裹起来保护:

const condition = authUser => !!authUser;
export default withAuthorization(condition)(DashboardPage));

所以,主App index.js 是:

const App = () => (
  <Router>
    <Switch>
      <Route exact path='/'  render={(props) => <LandingPage {...props} />}/>
      <Route exact path={ROUTES.LANDING}  render={(props) => <LandingPage {...props} />}/>
      <Route exact path={ROUTES.DASHBOARD}  render={(props) => <Dashboard {...props} />}/>
        ...
    </Switch>
  </Router>
);

export default withAuthentication(App);

因此,最初会向用户显示没有授权的登录页面。登录后,用户将被重定向到 Dashboard,这确实需要授权。

目前授权只是“用户是否登录?”,这很好。因此,用户、登录和(成功时)然后被重定向到仪表板,我们在那里检查他们是否已登录,然后显示页面。

但是,我希望授权更具体。我有不同类型的用户——比如说管理员和非管理员。只有管​​理员才能看到仪表板页面。此信息(用户是否为管理员)保存在我自己的数据库中 - 而不是 Firebase Auth 数据库中(我无法更改此设置)。所以,我需要能够做到以下几点:

  • 在用户点击“提交”时对用户进行身份验证 - 这将创建“authUser”并仅设置电子邮件地址
  • 然后检索附加信息 (isAdmin) 并将其添加到 authUser
  • 然后重定向到仪表板

我不知道如何在检索附加信息的中间步骤中插入。如果我将其作为“onSubmit”处理的一部分(因此在检索 authUser 之后但在重定向和触发授权之前),我无法在 authUser 中设置它。如果我在身份验证中执行此操作,则会在进行数据库调用之前调用授权,因此会失败。

我认为我需要某种回调,以便对用户进行身份验证,而不是从 onSubmit 重定向,我只能在提取数据后触发重定向。因此身份验证成功> authUser 仅填充电子邮件> 进行数据库调用并找到管理员状态> 然后重定向到仪表板。但我无法从身份验证中重定向,因为它不在路由器中。

【问题讨论】:

  • 成功登录后,即在您的.doSignInWithEmailAndPassword.then 调用中,您可以对其他数据库进行另一个AJAX 调用以检索额外信息,当成功时,这意味着它自己的@987654327 @call,您可以根据用户的类型决定将用户发送到哪里。

标签: reactjs


【解决方案1】:

您可以通过将顺序异步调用嵌套在前一个的 callack 中来链接顺序异步调用(不过要小心callback hell)。

在您的onSubmit 方法中,您可以对其他数据库进行AJAX 调用(我们称之为OtherDB)来检索有关成功登录用户的额外信息。在最后一次调用的回调中,您拥有有关用户的这些额外信息,您可以使用这些信息来决定将用户重定向到哪里(如果有的话)。

以下是关于代码外观的粗略概念:

onSubmit = (event) => {
    const { email, password } = this.state;

    this.props.firebase.doSignInWithEmailAndPassword(email, password)
    .then(() => {
        OtherDB.whatKindOfUserIsThis(email)
        .then((userType) => {
            if (userType === 'Admin') {
                this.setState({ ...INITIAL_STATE });
                this.props.history.push(ROUTES.DASHBOARD);
            }
            else {
                console.log('Nope');
            }
        })
        .catch(error => {
            this.setState({ error });
        });
    })
    .catch(error => {
        this.setState({ error });
    });

    event.preventDefault();
};

这种形式的代码应该可以解决问题,显然,这假设您在 UI 代码中引用了其他数据库,并且它有这样一个方法来响应有关给定用户的信息。

建议:这可能是一个不正确的假设,但是查看您现在拥有的代码,我注意到您的路线不受保护,从某种意义上说,如果用户直接在成功登录后浏览器,无论他们的类型如何,他们都会被重定向到那里,即使你使用我上面粘贴的代码。我假设您需要在 Authorization 组件中添加额外的保护,不仅可以检查用户是否登录,还可以检查他们的类型。

【讨论】:

  • 谢谢!是的,我将为授权组件添加额外的保护,以检查用户类型。目前我正在首先从数据库中检索用户类型。
  • 好的,这个解决方案并不能完全满足我的需求。我需要在 authUser 中设置用户类型,这样当我进入授权组件时,它可以检查 authUser.userType。我可以在身份验证中设置它,但我不能从那里重定向。我只能从 onSubmit 调用重定向,但它不能设置 authUser 值...
  • 为什么不能从那里设置authUser 值?您如何在 Dashboard 组件中获取此值?您应该能够在 Login 组件中执行相同的操作。如果没有,如何创建一个 AuthProvider 类来集中这些信息,以便应用程序中的所有内容都可以访问它?
  • 我正在使用 AuthConsumer 获取仪表板中的值;我会尝试在登录中做同样的事情。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-15
  • 2020-08-09
相关资源
最近更新 更多