【问题标题】:React router authentication反应路由器身份验证
【发布时间】:2018-12-19 22:22:57
【问题描述】:

我是 React.js 的初学者,我正在使用 Firebase 和 React Router。我已经建立了一个单独的Auth.js 文件(导出一个布尔值),我在其中存储了用户的身份验证状态并且它按预期工作,但问题是当我登录/注册或注销时内容不会改变/重新-使成为。在其他文件中记录导出的布尔值我发现它由于某种原因没有改变。

授权

import fire from './Fire';

var isAuth = false;
fire.auth().onAuthStateChanged(
    function (user) {
        if (user) {
            isAuth = true;
            console.log('Authed');
        } else {
            isAuth = false
            console.log('Not Auth');
        }
    }
);

export default isAuth;

然后是 Router.js

    import React, { Component } from 'react';
    import { Route, Switch, Redirect } from "react-router-dom";
    import Login from './components/common/Navbar/Login/Login';
    import Register from './components/common/Navbar/Register/Register';
    import Home from './components/common/Home/Home';
    import isAuth from './config/isAuth';
    import All from './components/All/All';
    import PrivateRoute from './config/PrivateRoute';

    class Router extends Component {
        constructor(props) {
            super(props);
            this.state = ({
                isAuth: isAuth
            });
        }

        componentWillMount() {
            this.setState = ({
                isAuth: isAuth
            });
        }

        render() {
            console.log('Router.js => ' + this.state.isAuth)
            return (
                <div>
                    <PrivateRoute exact path='/' component={Home} />
                    <PrivateRoute exact path='/register' component={ 
     this.state.isAuth ? Home : Register} />
                    <PrivateRoute exact path='/all' component={All} />
                    <Route exact path='/login' component={ this.state.isAuth ? Home : Login} />
                </div>
            );
        }
    }

export default Router;

最后是 PrivateRoute 组件,它是我从互联网上某人的代码中获取的。

import React from 'react';
import { Redirect, Route } from "react-router-dom";

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

export default PrivateRoute;

【问题讨论】:

  • 是的,link。由于某些原因,该项目没有从网站加载,但我复制了我认为的所有内容
  • 一定没有保存,抱歉。更新了! link
  • All.js 组件呢?
  • 里面没有什么重要的,只有一行div文本,但我现在也加了,再次抱歉。 LINK
  • 你有我可以使用的虚拟登录凭据吗?

标签: javascript reactjs firebase authentication react-router


【解决方案1】:

为了解决这个问题,我对您处理身份验证状态更改的方式进行了一些更改。请参阅以下更改:

Router.js

...
class Router extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isAuth: false
    };
  }

  componentDidMount() {
    fire.auth().onAuthStateChanged(user => {
      console.log("Router user", user);
      if (user) {
        localStorage.setItem("user", user); // Note the use of localStorage
        this.setState({ isAuth: true });
      }
    });
  }

  render() {
    return (
      <div>
        <Switch>
          <PrivateRoute
            exact
            path="/"
            component={Home}
            isLogged={this.state.isAuth}
          />
          <PrivateRoute
            exact
            path="/register"
            component={this.state.isAuth ? Home : Register}
            isLogged={this.state.isAuth}
          />
          <PrivateRoute
            exact
            path="/all"
            component={All}
            isLogged={this.state.isAuth}
          />
          <Route
            exact
            path="/login"
            component={this.state.isAuth ? Home : Login}
          />
        </Switch>
      </div>
    );
  }
}

export default Router;

记下我传递给PrivateRoute 组件的isLogged 属性,这可以确保可以从PrivateRoute 组件中访问当前的身份验证状态。我还使用 localStorage 来保持身份验证状态。

PrivateRoute.js

...
const PrivateRoute = ({ component: Component, ...rest }, isLogged) => (
  <Route
    {...rest}
    render={props =>
      rest.isLogged ? (
        <Component {...props} />
      ) : (
        <Redirect to={{ pathname: "/login" }} />
      )
    }
  />
);

export default PrivateRoute;

您会注意到我使用的是rest.isLogged 而不是isLogged 参数,由于某种原因,该参数始终未定义。 rest.isLogged 是从 Router 组件传递到此组件的。

Home.js

class Home extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isAuth: localStorage.getItem("user") || false
    };

    console.log("Home.js => " + this.state.isAuth);
  }

  render() {
    return (
      <div>
        {/* If logged => Welcome ; else => Login */}
        {this.state.isAuth ? <Welcome /> : <Login />}
      </div>
    );
  }
}

export default Home;

Home 组件中,我删除了isAuth 导入,因为它不起作用,然后我设置状态的isAuth 以从localStorage 获取用户。

从现在开始,我相信您可以弄清楚应用程序的其余部分。和平。

点击下方按钮查看codesandbox

【讨论】:

  • 非常感谢,它确实解决了这个问题,干杯约翰!
【解决方案2】:

我认为你这样做的方式不会改变 isAuth 状态。你可以试试这个解决方案吗?我希望它会工作

class Router extends Component {
    constructor(props) {
        super(props);
        this.state = ({
            isAuth: false
        });
    }

    componentDidMount() {
        fire.auth().onAuthStateChanged((user) => {
            if (user) {
               console.log(user);
               this.setState({ isAuth: true });
            } else {
               this.setState({ isAuth: false });
            }
        });
    }

    render() {
        console.log('Router.js => ' + this.state.isAuth)
        return (
            <div>
                <PrivateRoute exact path='/' component={Home}/>
                <PrivateRoute exact path='/register' component={ 
 this.state.isAuth ? Home : Register} />
                <PrivateRoute exact path='/all' component={All}/>
                <Route exact path='/login' component={ this.state.isAuth ? Home : Login} />
            </div>
        );
    }
}

【讨论】:

  • 不,仍然不起作用,但现在它甚至说 TypeError: this.setState is not a function at Object.next (Router.js:23) at index.cjs.js:1353 at index.cjs .js:1457 我记得在某处看到,为了在从文件导出时使状态正常工作,外部文件必须是一个反应/组件文件,以便它知道什么时候发生了变化以及做什么。我可能错了
  • 我认为你有这个错误,因为我忘记为 fire.auth 绑定(this)。你能再试一次吗?
  • 我无法绑定 fire.auth().onAuthStateChanged() 函数,能否请您写下我该怎么做,因为我不熟悉绑定链式函数
  • 我更新了我的代码。由于我对您的 fire.auth().onAuthStateChange() 不太熟悉,因此我不确定我的解决方案。如果还有错误,可以把代码发给我吗?
  • github.com/dnp1204/react-chat-client/blob/master/_client/src/…。查看链接,这就是我在我的应用中检查身份验证的方式
猜你喜欢
  • 1970-01-01
  • 2018-05-16
  • 1970-01-01
  • 2017-09-26
  • 1970-01-01
  • 2018-05-21
  • 2021-08-06
  • 2021-12-20
  • 2016-12-11
相关资源
最近更新 更多