2016-01-21 143 views
12

我在使用redux和反應路由器進行身份驗證時遇到了一些麻煩,希望對如何最好地解決我的問題進行一些說明。Universal Auth Redux&React路由器

我有一個登錄組件,提交時調度以下動作:

export const loginUser = (creds) => { 
    return dispatch => { 

    dispatch(requestLogin(creds)) 

    return fetch('http://127.0.0.1:4000/api/login', { 
     ... 
    }) 
     .then(res => { 
     dispatch(receiveLogin()) 
     browserHistory.push('/admin') 
     ... 
     }) 
     ... 
    } 
} 

的receiveLogin行動更新isAuthenticated標誌的狀態設置爲true。我的保護路由有以下的OnEnter鉤:

export default (state) => { 
    return { 
    path: '/', 
    component: App, 
    childRoutes: [ 
     { 
     path: 'protected', 
     component: Protected, 
     ... 
     onEnter(nextState, replaceState) { 
      const loggedIn = //check state.isAuthenticated 
      if (!loggedIn) { 
      replaceState(null, 'login') 
      } 
     } 
     } 
    ] 
    } 
} 

正如你所看到的,我傳遞的狀態作爲參數。這使我可以訪問服務器以及客戶端的初始狀態。但是,在我的登錄操作發生後,顯然onEnter鉤子仍將使用初始狀態。

我想知道的是在更新isAuthenticated標誌之後獲取當前狀態的最好方法,而不是在我的onEnter掛鉤中使用它。或者,我的方法是否完全有缺陷,我是否應該以完全不同的方式完成這項工作?

回答

24

我發現在我的應用程序中使用onEnter掛鉤並不是處理此類auth邏輯和連接到redux存儲的最佳方法。

其中一個(幾個)陷阱是,即使你可以登錄一個用戶到你的'保護'路線,如果他們要在'保護'下注銷,他們永遠不會被重定向到'登錄',因爲它wouldn不會觸發onEnter。

另一種方法是使用高階組件,參見Dan Abramov的post關於在mixins上使用它們,我發現它們在這方面也非常有用。關於如何使用它們,有幾個要點/例子,但我最近爲此專門創建了一個庫redux-auth-wrapper。它非常新,但我認爲它可能是有用的,並避免使用HOC的不正確的身份驗證,可能會導致infinite-loop-redirects一些危險。

使用HOC的想法是它應用於組件時以某種方式擴展其功能的功能。使用redux的用戶最有可能熟悉connect,以通過訂閱商店來增強組件。

在這種情況下,您編寫的組件不知道受到身份驗證/授權的保護,並且在應用HOC函數時,將返回具有給定檢查的新組件。如果這些通過,則返回被包裝的組件,否則用戶被重定向到登錄的地方(或者在其他地方,如果其授權問題)。 HOC利用componentWillMountcomponentWillReceiveProps生命週期方法來確定是否允許用戶查看給定組件。這允許支持在認證改變時重定向組件,即使路由不改變。

我還會在這裏查看類似策略的示例:https://github.com/joshgeller/react-redux-jwt-auth-example

這裏是一個使用onEnter作爲auth與一些商店欺騙的例子,但我相信它不會處理上述的邊緣情況: https://github.com/CrocoDillon/universal-react-redux-boilerplate/blob/master/src/routes.jsx

+0

我和Andrew有類似的問題,但我使用HOC。我的問題是用戶無法登錄,因爲它始終在響應從服務器返回之前檢查當前狀態 - 這意味着用戶無法登錄。有沒有辦法在redux商店中限制支票? – Abdi

+0

@Abdi是啊我在這裏遇到過類似的問題:https://github.com/mjrussell/redux-auth-wrapper/issues/30。我認爲解決方案只是添加一個標誌到你的redux商店(isUserFetched)或類似的東西,如果是的話 - 而不是執行重定向,在HOC中顯示一個替代頁面,而不是包裝組件。 (如加載頁面)。我想很快添加到我的圖書館,只是還沒有時間 – mjrussell

+0

我實際上設法解決問題,而不訴諸在中間頁面。我使用了redux-thunk - 這讓行動等待解決,然後我更新狀態,然後重定向。希望這是有道理的,但如果你有類似的問題,一定要看看[redux-thunk](https://github.com/gaearon/redux-thunk)。我還發現這個回購非常有幫助,因爲它正在做我想實現的[HOC with authentication](https://github.com/joshgeller/react-redux-jwt-auth-example) – Abdi