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

时间:2017-10-24 09:25:26

标签: reactjs authentication react-router

我正在使用react路由器v4并试图实现一个功能,无论用户点击什么路由,他都会被带到登录页面,即他是否已经登录。

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

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

 try (ConfigurableApplicationContext cxt = new ClassPathXmlApplicationContext(
                    "classpath:application-main-config.xml")) {..
}

现在,虽然这是正常的,但我不想为所有不同的路由一次又一次地重复相同的代码。那么有更好的方法吗?

现在,退出后,它没有显示任何内容,我希望它显示登录页面。因此我也添加了以下行,因此一旦用户注销它就会显示登录页面。

<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} />

但还有一个问题 - &gt;虽然在注销后它会显示登录组件,(仍显示路由为&#39; / logout&#39;)但它会将我带回登录表单(此时路由为&#39; / login&#39;)并且此路由登录将我带到仪表板。现在,为什么会发生这种情况?

在我还在学习反应路由器

时,会感谢一些帮助

4 个答案:

答案 0 :(得分: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>

getLoggedRouteList

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;
}

登录组件

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('/');
    }
  }
}

答案 1 :(得分:2)

example之后,你可以创建一个组件PrivateRoute来包装Route,并在需要使用auth的路由时使用它。

这是示例中的组件代码。

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

答案 2 :(得分:0)

这就是我最终做的方式:

<Switch>
  {loggedIn ? null : <Route path='/protectedPath' render={(props) => {
    const {pathname} = props.location
    // if the user tries to access a protected location, but is NOT logged in
    // remember the location the user was trying to access
    this.lastLocation = pathname
    // redirect to login page
    return <Redirect to='/loginPath' />
   }} />}
   <Route exact path='/loginPath' render={(props) => {
     return <Login {...props} lastLocation={this.lastLocation} />
   }} />
</Switch>

然后,在我的Login组件内部,检查lastLocation属性是否设置为检查登录后是否应重定向用户。

此解决方案唯一困扰我的是,在第一条路线的render方法内部使用了功能代码。但是因为它会立即重定向,所以我希望可以忽略它。

答案 3 :(得分:0)

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

将依存关系query-string添加到您的React应用。

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

history.push('/login');

但是我们可以将前一个作为查询传递,如下所示。我们可以使用useLocation

中的react-router来使用上一条路径
 const lastLocation = useLocation();
 history.push(`/login?redirectTo={lastLocation}`);

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

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

受到https://ui.dev/react-router-v4-query-strings/

的启发