2016-11-17 92 views
2

我有一个简单的API构建在Nodal中,它允许用户创建一个新的工作(实质上是一个服务业务的工单)。 API正在使用OAuth,因此为了创建新作业,用户必须首先通过用户名和密码进行身份验证来获取令牌。来自React App的API用户认证

前端将在React中构建。为了访问该网站,用户将不得不使用他们的用户名和密码登录,届时他们将获得一个令牌来进行API调用。两个问题:

1)如何安全地存储API令牌,以便用户在每次刷新页面时都不必登录?

2)如何使用这个相同的登录步骤来确定他们是否可以访问前端应用程序中的任何给定页面?

+2

将令牌存储在会话或本地存储中。在应用程序启动时公开端点以验证令牌。如果有一个令牌并且它仍然有效,那么让它们在不重新登录的情况下进入。如果没有令牌或它是无效的,那么将它们踢到登录屏幕并删除令牌(如果存在)。 – kentcdodds

+1

另请注意,客户端上的任何内容都不安全,因此您应该始终验证服务器端的输入(在这种情况下,仅在用户登录并提供令牌后才提供登录所需的页面)。 –

回答

4

这是我在当前项目中使用的过程。当用户登录时,我拿取令牌并存储在localStorage中。然后,每当用户转到任何路线时,我都会将路线服务的组件包装在一个特定的路径中。这是检查令牌的HOC的代码。

export function requireAuthentication(Component) { 

    class AuthenticatedComponent extends React.Component { 

     componentWillMount() { 
      this.checkAuth(this.props.user.isAuthenticated); 
     } 

     componentWillReceiveProps (nextProps) { 
      this.checkAuth(nextProps.user.isAuthenticated); 
     } 

     checkAuth (isAuthenticated) { 
      if (!isAuthenticated) { 
       let redirectAfterLogin = this.props.location.pathname; 
       browserHistory.push(`/login?next=${redirectAfterLogin}`); 
      } 
     } 

     render() { 
      return (
       <div> 
        {this.props.user.isAuthenticated === true 
         ? <Component {...this.props}/> 
         : null 
        } 
       </div> 
      ) 

     } 
    } 

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

    return connect(mapStateToProps)(AuthenticatedComponent); 
} 

然后在我的index.js我包裹每个受保护的路径与此HOC像这样:

<Route path='/protected' component={requireAuthentication(ProtectedComponent)} /> 

这是用户减速器的外观。

export default function userReducer(state = {}, action) { 
    switch(action.type) { 
     case types.USER_LOGIN_SUCCESS: 
      return {...action.user, isAuthenticated: true}; 
     default: 
      return state; 
    } 
} 

action.user包含令牌。令牌可以来自用户首次登录时的API,也可以来自本地存储,如果该用户已经是登录用户。

+0

注意到mapStateToProps。这是一个Redux应用程序吗?如果是这样,你可以分享更多关于认证层和'isAuthenticated'的设置吗? –

+0

这是一个REDX应用程序。 isAuthenticated设置在减速器中。我可以编辑我的答案来显示代码。 –