トークンをlocalstorageに保存することにより、どのようにユーザーのログインを維持しますか?

Aug 23 2020

私はこのチュートリアルに従って認証を実装しています: https://medium.com/technest/implement-user-auth-in-a-django-react-app-with-knox-fc56cdc9211c

ユーザーがアプリのベースURLにアクセスすると、認証されていない場合はログインページにリダイレクトされます。これは私のapp.jsがどのように見えるかです:

class App extends Component {
  componentDidMount() {
    store.dispatch(loadUser());
  }

  render() {
    return (
      <Provider store={store}>
        <Router>
          <Sidebar />
          <Switch>
            <PrivateRoute exact path='/' component={Dashboard} />
            <Route exact path='/feed' component={Feed} />
            <Route exact path='/register' component={RegisterForm} />
            <Route exact path='/login' component={LoginForm} />
            
          </Switch>
        </Router>
      </Provider>

    );
  }
}

export default App;

私のPrivateRoute.js:

const PrivateRoute = ({ component: Component, auth, ...rest }) => (
  <Route
    {...rest}
    render={props => {
      if (auth.isLoading) {
        return <div>Loading...</div>;
      } else if (!auth.isAuthenticated) {
        return <Redirect to='/login' />;
      } else {
        return <Component {...props} />;
      }
    }}
  />
);

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

export default connect(mapStateToProps)(PrivateRoute);

ここでは、認証は正常に機能し、Dashboard.jsコンポーネントに正しくリンクしています。Dashboard.js内で、ユーザーのプロファイルを表示するProfile.jsと呼ばれる別のコンポーネントをレンダリングしています。

最初に示したコード(App.js)では、タグの外側に、ユーザーがログインしているかどうかに関係なく常にレンダリングされるSidebar.jsコンポーネントがあります。

class Sidebar extends Component {
// Button event to switch to feed page.
  render() {
    const { user, isAuthenticated } = this.props.auth;

    return (
        <>
        <div id="sidebar">
            <a onClick={this.props.logout} id="logout_btn">
                <span className="fa fa-lock"></span></a>
            <NavLink id="profile_btn" to="/">
                <span className="fa fa-user-circle"></span></NavLink>
            <NavLink id="feed_btn" to="/feed">
                <span className="fa fa-address-book"></span></NavLink>
        </div>
        <div id="brand">
            <h1>Cook Simple</h1>
            <p id="username-goes-here"></p>
            <a id="add_btn" href="{% url 'recipe:recipe_new' %}">
                <span class="fa fa-plus"></span> </a>
        </div>
        </>
    );
  }
}

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

export default connect(mapStateToProps, { logout })(Sidebar);

このサイドバーには、前述のプロファイルにリンクする1つのボタンと、フィードと呼ばれる別のコンポーネントにリンクする別のボタンがあります。[プロファイル]ボタンをクリックすると正常に機能します。ベースURLに移動し、PrivateRouteに移動し、ユーザーが認証されていることを確認して、プロファイルをレンダリングします。ただし、フィードのボタンをクリックすると、prop'auth 'が未定義であることが示されます。フィードのコード:

class Feed extends Component {
  componentDidMount() {
    this.props.getAllRecipes();
  }
  setGrid() {
    try {
      document.getElementById("grid-container-PROFILE").id = "grid-container-FEED"
      console.log("Feed Loaded")
    }
    catch {
      console.log("Feed Already Loaded")
    }
  }

  render() {
    this.setGrid()
    return (
    <>
      <div id="brand">
        <h1>Title Goes Here</h1>
      </div>

      <div className="title-FEED" id="recipecards-FEED">
        <div id="recipecard-container-FEED">
          <RecipeList />
        </div>
      </div>
    </>
    );
  }
}

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

const mapDispatchToProps = () => {
  return {
    getAllRecipes,
  }
}

export default connect(mapStateToProps, mapDispatchToProps())(Feed)

このコンポーネント内で、auth.userにアクセスして、ユーザーオブジェクト内のデータをレンダリングできるようにしたいと思います。ただし、authが定義されていないようです。

認証に使用しているアクションとレデューサーは、リンクされたチュートリアルと同じです。ここに彼らの要点があります:

認証アクション: https://gist.github.com/kjmczk/2c287f1d615824c627580bd2a8067fcb#file-auth-js

認証レデューサー: https://gist.github.com/kjmczk/64f302546e4cd38ff922cf5d59192b8e#file-auth-js

回答

HeshieBee Aug 24 2020 at 04:04

構文エラーがあるようです。交換してみてください:

connect(mapStateToProps, mapDispatchToProps())(Feed);

と:

connect(mapStateToProps, mapDispatchToProps)(Feed);

括弧を削除します。

oqukeun Aug 24 2020 at 20:31

問題を見つけました。React DevToolsで小道具を見ると、すべてのコンポーネントに認証小道具があるように見えましたが、実際に使用しようとするとエラーが発生しました。ユーザーが認証されていることを確認した後、小道具にアクセスするだけでこれを修正しました。