【问题标题】:React routing and private routes反应路由和私有路由
【发布时间】:2018-11-05 23:37:49
【问题描述】:

如果用户在允许访问之前已登录,我正在尝试通过检查我的快速服务器来阻止对私有路径的访问,否则重定向到登录。

我创建了一个与服务器检查的私有路由函数。问题是,我不知道如何让它等待响应,然后再决定路由到哪个组件(私人页面与登录)。

const isAuthed = () => {
  fetch('/api/checkLogin', {
    method: 'GET',
    credentials: 'include'
  })
  .then(response => {
    console.log(response.status == 200);
    return response.status == 200;
  });
}

const PrivateRoute = ({ component: Component, ...rest }) => {
    return (
      <Route
        {...rest}
        render={props =>
          isAuthed() == true ? (
            <Component {...props} />
          ) : (
            <Redirect
              to={{
                pathname: "/login",
                state: { from: props.location }
              }}
            />
          )
        }
      />
    );
  }

这总是重定向到登录...

有什么想法吗?

编辑 1 以下是 PrivateRoute 的使用方式。

const Routing = (props) => (
  <div>
    <Switch>
      <Route exact path='/' component={Home} />
      <PrivateRoute exact path='/profile' component={Profile} />
      <PrivateRoute exact path='/auction_list' component={Auctions} />
    </Switch>
  </div>
)

有了反应,似乎我在调用路由组件时必须返回一些东西。我无法对 PrivateRoute 进行异步调用,然后让该异步调用返回更新。

编辑 2 我尝试使用 react-redux 来存储登录数据,这样我就不必对服务器进行异步调用来进行身份验证。但是,刷新页面会清除所有 redux 存储,所以就好像用户在刷新后没有登录一样,这很笨拙。

我想把信息放在会话存储中。但是用户将无法一次注销所有机器。

我最终从每个私有组件的 componentWillMount ping 服务器。私人页面可能会闪烁几分之一秒,但这是迄今为止我能做的最好的……如果有更好的方法,请告诉我……一定有。

【问题讨论】:

  • 是的。 IsAuthed 没有返回 true。
  • IsAuthed 如果我们等待 fetch 返回响应(如果用户被授权)@fabbb,将返回 true
  • isAuthed() 是一个异步调用,当作为普通方法调用时将返回 undefined,因此 isAuthed() == true 将始终为 false。理想的方法是在父组件中进行异步调用并将isAuthenticated 作为道具传递给 PrivateRoute 组件。

标签: javascript reactjs


【解决方案1】:

您不应该在用户每次访问网站时都通过服务器进行身份验证。

react-router的条件路由只有在条件可以同步检查的情况下才有效。

当用户第一次成功通过身份验证时,您将指示身份验证状态的变量(如果需要,还可以包含到期日期)存储到localStorage。

当用户再次访问该网站时,您将能够通过从localStorage 获取身份验证状态进行重定向(这是一个同步操作)。

【讨论】:

  • 是的,有点感觉我每次访问都无法检查服务器。我可能会将身份验证状态存储在 sessionStorage 中。您对使用服务器身份验证状态更新 sessionStorage 的最佳方法有什么想法吗?例如:用户登录...转到另一台计算机,注销,返回到第一台计算机,访问私人站点...sessionStorage 仍然会说它已经过身份验证。
  • 您可以执行异步身份验证(在呈现PrivateRoute 之后),因此在重定向之前(当 API 调用返回时)用户仍会看到私有页面一小段时间。另一种方法是在异步身份验证完成之前呈现加载页面(例如使用微调器),但这通常不是一个好的用户体验。
  • 所以如果我在 localStorage 中添加番茄,这将允许我访问受保护的页面!?
  • @HasanDaghash 是的,但用户将无法获取更新的数据,因为 AJAX 调用将因身份验证 cookie 无效而失败,因此页面将仅包含空/过时的数据。这就是现代 SPA 的工作方式,因为无论如何客户都将拥有页面视图的(缩小的)源代码。
  • 我怀疑 Angular 有 canActivate 并且它处理得很好这部分,但在反应中我仍在探索最佳实践
【解决方案2】:

让用户访问私有路由对我来说似乎很奇怪。哪怕只是风景。我知道当涉及到数据库时,他们将无法访问任何操作,但这似乎仍然是一个缺陷。我还尝试与服务器检查受保护路由上的每个请求,并最终遇到了同样的问题。解决这个问题的唯一方法是让实际的屏幕/页面进行调用并验证 JWT 令牌。我认为就我而言,这就足够了。

【讨论】:

    猜你喜欢
    • 2020-08-24
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    • 2020-10-22
    • 2020-03-04
    • 2021-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多