2016-06-28 48 views
1

假設您正在開發通過第三方api執行認證的前端應用程序。成功的身份驗證會返回一個json Web令牌。標籤打開時會話的認證邏輯

什麼是最佳實踐來存儲這樣的令牌併爲用戶創建某種類型的會話,同時他在網站上處於活動狀態,即不關閉標籤頁或瀏覽器,但是刷新/重新加載頁面不應該破壞這樣的會話。

另外,該會話如何用於保護路由?我正在使用由react/redux/node/express組成的堆棧以及其他一些庫。我相信我可以在我的反應路由器中執行某些檢查,但是在明確的方面做這些不是更好嗎?

+0

'sessionStorage'在服務器會話? – pawel

回答

2

您可以將標記存儲在localStoragesessionStorage中,並將其包含在每個API請求中。

Local storage超出選項卡,它存儲在那裏,直到你明確地從它刪除,所以刷新頁面不會是一個問題。即使關閉一個標籤,然後回來也不會。

Session storage允許您存儲數據。頁面刷新沒問題,但Tab鍵關閉不是,這更接近你想要的行爲。

至於保護路由,服務器應該明確地檢查對所有受保護的API路由請求的令牌。

在瀏覽器端,如果用戶試圖訪問受保護的路由但令牌不存在(或無效),則可能需要顯示登錄表單。

隨着反應的路由器,你可以做這樣的官方回購顯示的示例中,通過onEnter鉤:https://github.com/reactjs/react-router/blob/master/examples/auth-flow/app.js

另一種方法是創建兩個頂層組件,一個受保護的途徑,一個是公共路線(如登陸頁面或登錄/註冊表單)。受保護的處理程序將隨後在componentWillMount檢查,如果有一個令牌:

- PublicHandler 
    + SignIn 
    + SignUp 
    + Index 

- ProtectedHandler 
    + Dashboard 
    + MoneyWithdrawal 
+0

我只是想到了一個想法,如果有人用隨機字符串設置會話,他們將獲得對'/ dashboard'的訪問,顯然他們不會在那裏看到任何數據,因爲隨機字符串不是有效的標記,但仍然可以訪問受限制的路由 – Ilja

+0

但是沒有後端,它將不可用。你可以做的是,首先用令牌調用服務器來查看它是否有效。如果是 - 一切正常,否則重定向到登錄表單。 –

1

它可能看起來像,與的sessionStorageJWT令牌accesseble,直到瀏覽器或片閉合)

///action creator redux 
export const signupUser = creds => dispatch =>{ 
    dispatch(requestSignup()); 

    return API.auth.signup(creds) 
    .then(res => { 
     sessionStorage.setItem('token', res.token);// <------------------ 
     dispatch(receiveSignup(res)); 
     return res; 
    }) 
    .catch(err => { 
      dispatch(SignupError(err)); 
     ); 
    }); 

}; 

在客戶端:通過HOC處理驗證碼redux-auth-wrapper

在服務器上服務器上就可以使用passport-jwt戰略

passport.use('jwt',new JwtStrategy(opts, function(jwt_payload, done) { 
     User.findOne({where:{ id: jwt_payload.user.id }}).then(user=>{ 
      if (user) { 
       done(null, jwt_payload.user); 
      } else { 
       done(null, false); 
       // or you could create a new account 
      } 
     },err=>{ 
      console.log('Error ',err); 
      return done(err,false); 
     }); 

    })); 

然後只需添加路由處理

var checkJWT = passport.authenticate('jwt') 

router.get('/protected',checkJWT, (req, res) =>{ 
    res.json(req.user); 
}); 

你不需要爲