重定向到登录时的上一个路径-React Router v4

far*_*raz 7 authentication reactjs react-router

我正在使用React Router v4并尝试实现一项功能,无论用户单击什么路由,他都会转到登录页面,即如果他尚未登录。

但是登录后,他被重定向到他尝试在登录前访问的同一页面

我已经使用以下代码设法对其中的两条路线进行了此操作,但不确定这是否是最佳方法

<Route path="/dashboard" render={(props) => (
    auth ? 
    (<MainDash props={this.props} />) 
    : 
    (<Redirect to="/login"/>)
    )}
/>
<Route exact path="/customers" render={(props) => (
    auth ? 
    (<MainApp />) 
    : 
    (<Redirect to="/login"/>)
    )}
/>
<Route exact path="/staff" render={(props) => (
    auth ? 
    (<MainApp />)
    : 
    (<Redirect to="/login"/>)
    )}
/>
<Route path="/login" component={Login} />
<Route path="/logout" component={Login} />
Run Code Online (Sandbox Code Playgroud)

现在,尽管这可以正常工作,但我不想为所有不同的路线重复一次相同的代码。所以有更好的方法吗?

现在,注销后,它什么也没显示,我希望它显示登录页面。因此,我也添加了以下几行,以便用户注销后立即显示登录页面。

<Route path="/login" component={Login} />
      <Route path="/logout" component={Login} />
Run Code Online (Sandbox Code Playgroud)

但是还有一个问题->尽管注销后它确实显示了登录组件(仍然将路由显示为'/ logout'),但它带我回到了登录表单(这次路由是'/ login'),并且从该路由登录将我带到仪表板。现在,为什么会这样呢?

希望能对此有所帮助,因为我仍在学习React Router

spi*_*ift 5

按照此示例,您可以制作PrivateRoute要包装的组件,Route并在需要需要身份验证的路由时使用它。

这是示例中的组件代码。

const PrivateRoute = ({ component: Component, ...rest }) => (
    <Route {...rest} render={props => (
            fakeAuth.isAuthenticated ? 
            (<Component {...props}/>) 
            : 
            (
              <Redirect to={{
                    pathname: '/login',
                    state: { from: props.location }
                }}
              />
            )
        )}
    />
)
Run Code Online (Sandbox Code Playgroud)


Joh*_*iao 5

以前的答案不够详细。

解决方案:

路由器

<BrowserRouter basename={BASE_NAME}>
  <Switch>
    {publicRouteList()}
    <Route exact key="login" path="/login" component={Login} />
    {getLoggedRouteList(state.logged)}
    <Redirect key="redirect-login" to="/login" />
  </Switch>
</BrowserRouter>
Run Code Online (Sandbox Code Playgroud)

获取记录路由列表

const getLoggedRouteList = (logged) => {
  if (!logged) {
    return (
      <Route
        key="wait-login"
        render={props => {
          return (
            <Redirect
              to={{
                pathname: '/login',
                state: { from: props.location },
              }}
            />
          );
        }}
      />
    );
  }

  const output = [];
  output.push(
    /* Here place route list that need logged */
  );
  return output;
}
Run Code Online (Sandbox Code Playgroud)

登录组件

class Login extends React.Component {
  login = async param => {
    const { location } = this.props;
    const { state } = location;

    /* Here place request login api */

    // go to state.from if set before
    if (state && state.from) {
      history.replace(state.from);
    }
    // else go to home
    else {
      history.replace('/');
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


Pan*_*ara 5

您可以使用查询字符串来完成此操作。

将依赖项查询字符串添加到您的反应应用程序中。

每当用户尝试访问受保护的路径时,如果用户尚未登录,则必须重定向到登录屏幕。为此,您将执行类似的操作。

history.push('/login');
Run Code Online (Sandbox Code Playgroud)

但我们可以将前一个作为查询传递,如下所示。useLocation我们可以使用from 来获取之前的路径react-router

 const lastLocation = useLocation();
 history.push(`/login?redirectTo=${lastLocation}`);
Run Code Online (Sandbox Code Playgroud)

现在登录成功后,我们可以获取之前路径中传递的查询字符串。如果之前的路径是 ,我们可以设置一个默认路径null

 const handleSuccessLogin = () => {
      const location = useLocation();
      const { redirectTo } = queryString.parse(location.search);
      history.push(redirectTo == null ? "/apps" : redirectTo);
 };
Run Code Online (Sandbox Code Playgroud)

灵感来自https://ui.dev/react-router-v4-query-strings/