您如何通过在 localstorage 中存储令牌来保持用户登录状态? [英] How do you keep user logged in using by storing tokens in localstorage?

查看:59
本文介绍了您如何通过在 localstorage 中存储令牌来保持用户登录状态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在按照本教程实施身份验证:https://medium.com/technest/implement-user-auth-in-a-django-react-app-with-knox-fc56cdc9211c

当用户访问我的应用程序的基本 url 时,如果他们未通过身份验证,它会将他们重定向到登录页面.这是我的 app.js 的样子:

class App 扩展组件 {componentDidMount() {store.dispatch(loadUser());}使成为() {返回 (<提供者商店={商店}><路由器><侧边栏/><开关><PrivateRoute 精确路径='/' component={Dashboard}/><路由精确路径='/feed' component={Feed}/><路由精确路径='/register' component={RegisterForm}/><路由精确路径='/login' component={LoginForm}/></开关></路由器></提供者>);}}导出默认应用程序;

我的 PrivateRoute.js:

const PrivateRoute = ({ component: Component, auth, ...rest }) =>(<路线{...休息}渲染={道具=>{如果(auth.isLoading){返回<div>加载中...</div>;} else if (!auth.isAuthenticated) {return <Redirect to='/login'/>;} 别的 {return <Component {...props}/>;}}}/>);const mapStateToProps = state =>({身份验证:state.auth});导出默认连接(mapStateToProps)(PrivateRoute);

在这里,身份验证工作正常,并正确链接到我的 Dashboard.js 组件.在我的 Dashboard.js 中,我只是渲染了另一个组件,称为 Profile.js,用于显示用户的个人资料.

在我展示的第一个代码 (App.js) 中,在标签之外,我的 Sidebar.js 组件始终呈现,无论用户是否登录.

class Sidebar extends Component {//切换到提要页面的按钮事件.使成为() {const { user, isAuthenticated } = this.props.auth;返回 (<><div id="侧边栏"><a onClick={this.props.logout} id=logout_btn"><span className="fa fa-lock"></span></a><NavLink id="profile_btn";到=/"><span className="fa fa-user-circle"></span></NavLink><NavLink id="feed_btn";to=/feed"><span className="fa fa-address-book"></span></NavLink>

<div id="品牌"><h1>Cook Simple</h1><p id="用户名-转到此处"></p><a id="add_btn";href={% url 'recipe:recipe_new' %}"><span class="fa fa-plus"></span></a>

</>);}}const mapStateToProps = state =>({身份验证:state.auth});export default connect(mapStateToProps, { logout })(Sidebar);

在这个侧边栏上,我有一个按钮链接到上述配置文件,另一个按钮链接到另一个名为 Feed 的组件.单击个人资料"按钮工作正常 - 它转到我的基本网址,该网址转到 PrivateRoute,看到用户已通过身份验证,并呈现个人资料.但是,单击 Feed 按钮显示道具auth"未定义.Feed 的代码:

class Feed 扩展组件 {componentDidMount() {this.props.getAllRecipes();}设置网格(){尝试 {document.getElementById("grid-container-PROFILE").id = "grid-container-FEED";console.log("Feed Loaded")}抓住 {console.log(Feed 已经加载")}}使成为() {this.setGrid()返回 (<><div id="品牌"><h1>标题在这里</h1>

<div className="title-FEED";id=食谱卡-饲料"><div id="recipecard-container-FEED"><食谱列表/>

</>);}}const mapStateToProps = (状态) =>{返回 {all_recipes: state.all_recipes,身份验证:state.auth}}const mapDispatchToProps = () =>{返回 {获取所有食谱,}}导出默认连接(mapStateToProps, mapDispatchToProps())(Feed)

在这个组件中,我希望能够访问 auth.user 来呈现用户对象中的一些数据.但是,似乎 auth 未定义.

我用于身份验证的操作和减速器与链接教程相同.以下是他们的要点:

身份验证操作:https://gist.github.com/kjmczk/2c287f1d615824c627580bd2a8067fcb#file-auth-js

auth reducers:https://gist.github.com/kjmczk/64f302546e4cd38ff922cf5d59192b8e#file-auth-js

解决方案

我发现了这个问题.当使用 React DevTools 查看我的道具时,组件似乎都有 auth 道具,但是每当我尝试实际使用它时,我都会出错.在检查用户是否通过身份验证后,我仅通过访问 prop 解决了这个问题.

I am following this tutorial to implement authentication: https://medium.com/technest/implement-user-auth-in-a-django-react-app-with-knox-fc56cdc9211c

When the user goes to my app's base url, it redirects them to a login page if they are not authenticated. This is what my app.js looks like:

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;

My 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);

Here, the authentication works fine, and correctly links to my Dashboard.js component. Within my Dashboard.js, I am just rendering another component I have, called Profile.js, which displays users' profiles.

In the first code I showed (App.js), outside of the tags, I have my Sidebar.js component that is always rendered regardless of whether the user is logged in.

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

On this sidebar, I have one button that links to the aforementioned Profile and another button that links to another component called Feed. Clicking the Profile button works fine - it goes to my base url, which goes to the PrivateRoute, sees that the user is authenticated, and renders the Profile. However, clicking the button for Feed shows that the prop 'auth' is undefined. The code for Feed:

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)

Within this component, I would like to be able to access auth.user to render some data within the user object. However, it appears that auth is undefined.

The actions and reducers I am using for authentication is the same as the linked tutorial. Here are their gists:

auth actions: https://gist.github.com/kjmczk/2c287f1d615824c627580bd2a8067fcb#file-auth-js

auth reducers: https://gist.github.com/kjmczk/64f302546e4cd38ff922cf5d59192b8e#file-auth-js

解决方案

I found the issue. When looking at my props with React DevTools, the components seemed to all have the auth prop, but whenever I tried to actually use it, I got an error. I fixed this by only accessing the prop after checking that the user is authenticated.

这篇关于您如何通过在 localstorage 中存储令牌来保持用户登录状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆