当前位置: 首页 > 知识库问答 >
问题:

react react-router-dom私有路由不工作时,从cookie异步加载身份验证令牌

郗鹏
2023-03-14

我有一个react/redux应用程序,使用“react router dom”进行路由。我在我的App.js中使用了以下内容(标记为react bootstrap,以提供私有路由。如果且仅当用户未登录时(基于cookie的存在),预期行为将重定向到/login)。实际行为是,即使用户登录,应用程序也会立即重定向到/login

class MainContainer extends Component {
  constructor(props) {
    super(props);
    this.props.loadAuthCookie();
  }

  PrivateRoute = ({ component: ChildComponent, ...rest }) => {
    return (
      <Route
        {...rest}
        render={(props) => {
          if (!this.props.auth.loggedIn && !this.props.auth.authPending) {
            return <Redirect to="/login" />;
          } else {
            return <ChildComponent {...props} />;
          }
        }}
      />
    );
  };

  render() {
    const { PrivateRoute } = this;
    return (
      <Router>
        <Container fluid id="root">
          <Header />
          <Switch>
            <Row className="pageContainer">
              <Col>
                <PrivateRoute exact path="/" component={HomeScreen} />
                <Route
                  exact
                  path="/clusters/"
                  component={clusterOverviewScreen}
                />
                <Route exact path="/login" component={LoginPage} />
              </Col>
            </Row>
          </Switch>
        </Container>
      </Router>
    );
  }
}

const mapStateToProps = (state) => {
  return {
    auth: state.auth,
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    loadAuthCookie: () => {
      return dispatch(loadAuthCookie());
    },
  };
};

const RootContainer = connect(
  mapStateToProps,
  mapDispatchToProps
)(MainContainer);

export default class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <RootContainer />
      </Provider>
    );
  }
}

函数this.props.loadAuthCookie发送一个redux操作,该操作将提取包含auth令牌(如果存在)的cookie,并将其置于状态。初始状态为

{
    "authPending": false
    "loggedIn": false
    "authToken": null
}

它变成:

{
    "authPending": true
    "loggedIn": false
    "authToken": null
}

最后:

{
    "authPending": false
    "loggedIn": true
    "authToken": TOKEN
}

我是一个比较新的反应。我的猜测是,在PrivateRoute函数运行时,redux操作尚未设置状态,因此PrivateRoute组件将重定向到登录页面。这个猜测是基于私有路由中的日志记录props.auth.loggedIn,返回false,但是当我重定向到的登录页面完成加载时,组件props声明This.props.loggedIn为true。不过,我不确定如何修复这个问题。

编辑:loadAuthCookie操作:

export const loadAuthCookie = () => (dispatch) => {
  dispatch(AuthReducer.setAuthPending());
  try {
    const cookie = Cookies.get("token");
    if (cookie) {
      dispatch(AuthReducer.setLoginSuccess(cookie));
    }
  } catch (err) {
    console.log(err);
    dispatch(AuthReducer.setLogout());
  }
};

共有2个答案

山鸿彩
2023-03-14

我认为托尼是对的;您可能需要调用this.props.loadAuthCookie() 组件生命周期的后面部分。

当(且仅当)组件被实例化时,构造函数才会运行;与安装或渲染时相反。构造函数通常在装入或呈现之前调用一次。

因此,调用this.props.loadAuthCookie()可能在componentDidMount内部也能工作,但我还是同意Tony的建议,在render()函数中尝试一下。

强德厚
2023-03-14

私人路由似乎实现不正确。

它应设计为“等待”,直到authPending变为falseloggedIn变为true

但在现实中,它要求两者都为真,这样它就不会重定向到登录。因此,如果authPending:true直到loggedIn:true,则实现“等待”。

以下是结果表。

也不要使用像这样的条件!洛格丁

<Route
    {...rest}
    render={(props) => {
        if (this.props.auth.loggedIn) {
            return <ChildComponent {...props} />;
        } else if (this.props.auth.authPending) {
            return <LoadingScreen/> // Or could simply div with text. Not different component
            // Then state updates after x seconds and re-renders
        } else {
            return <Redirect to="/login" />;
        }
    }}
/>

编辑:我实际上弄错了逻辑,要么是AuthPding

function test(first, second) {
    if (!first && !second) {
        console.log('login');
    } else {
        console.log('child');
        
    }
}

test(true, true);
test(false,false);
test(true, false);
test(false, true);

输出:

child
login
child
child

看,我还是不能动脑!;

 类似资料:
  • 关于未解决的问题(作为最终结论) react路由器dom v4中的多个嵌套路由 如何在React路由器v4中嵌套路由 我也有同样的问题。 https://reacttraining.com/react-router/web/guides/quick-start促进react-router-dom 此外,人们发现最好在一个文件中列出路由,而不是在组件内部。 有人提到:https://github.c

  • MyFireBaseMessagingService.Class MyFireBaseInstanceIDService.Class signOutAccount方法

  • https://reacttraining.com/react-router/web/example/auth-workflow 我在react-router-dom文档中实现的Private路由 PrivateRoute是从Redux存储获取身份验证状态的已连接组件。 我正在尝试使用redux模拟存储和mount from Ezyme测试连接的组件。 即使状态中的身份验证为真,传递给私人路由的组

  • 问题内容: 我正在尝试为我的支票写支票。但是该函数本身并未被调用。有人可以给我一些解决方案吗?我正在用ReactJs开发。 这是路线部分: 这是功能: 问题答案: 在,你可以利用来与生命周期方法一起更换功能存在于反应路由器V3。 查看此答案以获取更多详细信息: react-router v4中的onEnter prop 但是,由于您要做的只是在onEnter道具中进行身份验证,因此您可以轻松创建一

  • 问题内容: 我在glassfish服务器上使用了gwt,并且尝试通过cookie对我的某些RPC调用进行身份验证。这可能吗?有没有关于如何编码的示例? 问题答案: 仅依靠cookie进行身份验证将使您的网站/服务容易受到跨站点请求伪造/ XSRF / CSRF攻击- 有关GWT应用程序安全性的更多信息,请阅读。 最好的方法是再次检查从cookie以及通过其他方式(作为请求的一部分(标头,自定义字段