2016-11-17 96 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設置在減速器中。我可以編輯我的答案來顯示代碼。 –