2017-08-08 27 views
2

如下圖所示,我有一個獨立的API項目在服務器上運行,端口號爲3001,我有一個運行在端口爲3002的服務器上的Web App。端口如何使用遠程NodeJS API使用Passport.js驗證和授權客戶端Web應用程序

Flow of Web APP to API

API,擁有所有獲取並把數據所需的Web應用程序(&移動應用)的API路線,包括驗證API(使用passport-localpassport-jwt)。在項目的API方面,我也處理了用戶角色授權,每個路由都有可以訪問這些API的角色列表。在端口登錄後3001

exports.roleAuth = function(roles){ 

    return function(req, res, next){ 

     var user = req.user; 

     User.findById(user._id, function(err, foundUser){ 

      if(err){ 
       res.status(422).json({error: 'No user found.'}); 
       return next(err); 
      } 

      if(roles.indexOf(foundUser.role) > -1){ 
       return next(); 
      } 

      res.status(401).json({error: 'You are not authorized to view this content'}); 
      return next('Unauthorized'); 

     }); 
    } 
} 

響應JSON

示例路線

todoRoutes.get('/', 
       requireAuth, 
       AuthController.roleAuth(['user','editor','admin']), 
       TodoController.getTodos); 

角色授權API方法成功是這樣

{ 
    "token": "JWT eyJhbGci...", 
    "user": { 
     "_id": "5986b81d940bab06ddc79b34", 
     "email": "[email protected]", 
     "role": "admin" 
    } 
} 

現在Web App中,我想用同樣的角色授權和認證(登錄),但是你看,Web應用程序未連接到數據庫,對我做出那樣檢查查詢,如果在會話的用戶是有效的,在成功登錄後的響應中具有角色。

摘要 這裏是什麼,我在這個問題尋找的要點:

  1. 在客戶端Web應用程序登錄在3001端口上,通過遠程API(實現)
  2. 獲得用戶令牌和其他信息(上面顯示的響應)(已實現)
  3. 確保用戶在客戶端Web應用程序上進行身份驗證,並且還記住用戶登錄的角色,將這些信息用於每個客戶端應用程序中的路線。在客戶端應用程序中,我有幾頁表單向端口號發送數據到服務器端API,這些頁面被兩個不同的用戶使用,角色分別爲編輯器admin

TIA

+0

所以API沒有認證但沒有RBAC,但是webapp想要實現一個RBAC。對? – tbking

+0

API具有認證和RBAC(適用於所有apis),現在web應用程序想要使用apis以及RBAC,RBAC for Web應用程序用於控制視圖,而RBAC for API用於控制對控制器和讀取的訪問權限,寫入數據。 –

+0

嘿!我已經添加了答案。感謝您的解釋。 – tbking

回答

0
exports.roleAuth = function(roles){ 

return function(req, res, next){ 

    var user = req.user; 

    User.findById(user._id, function(err, foundUser){ 

     if(err){ 
      res.render('index.html'); 
     } 

     if(roles.indexOf(foundUser.role) > -1){ 
      res.render('another.html'); 
     } 

     res.render('another2.html'); 

    }); 
} 

}

+0

我無法理解你想用這段代碼說什麼。 –

+0

在你的問題中,你提到了你想根據你的角色來管理你的視圖,那我用'res.render'完成了什麼 –

+0

上面的代碼在API服務器上,API服務器不處理任何視圖,檢查路由如何放置在主API服務器上。 –

0

有兩種方法,我看這是可以做到,雖然不是完美的。

一種是使用一個特定視圖的主API端點。通常,每個視圖有一個主要終點,而如果該端點返回Unauthorized/Forbidden狀態,你不應該渲染視圖。但是這個解決方案有問題,並不總是有一個匹配視圖的主要端點。

其他選項是命名空間與角色的路線,如admin/dashboardusers/dashboard,並且用戶應該有一個字段描述他們的角色,例如。 user.role。在渲染視圖之前,請檢查API返回的url和user對象中的相應角色。

第二個選項是首選,這是我通常使用的。

希望它有幫助。

+0

感謝您的回答,我無法理解如何使用此應用程序的整體認證。你能不能讓我明白這一點。 –

+0

從您在問題中的新編輯中,我瞭解到您已經在API服務器中完成基於角色的身份驗證,現在您想以某種方式使用它來限制客戶端的用戶可訪問的路由。有很多方法可以做到這一點。首先,如果客戶端沒有限制,那麼API服務器應始終將用戶在會話中的角色與端點所需的角色(您可以輕鬆實現,如我的答案中所示)相匹配。 其次,您還可以從客戶端的JWT等中讀取用戶角色,並阻止呈現其他角色的用戶並提交其他用戶。 – tbking

+0

你能幫我一個例子代碼嗎? –

0

JWT的美不是已經解決了這個問題,還是可以通過正確的實現來解決您的問題?

所有需要的是你

  1. 初始化你的Web應用程序模塊passport-jwt你初始化它在你的API,即secretOrKey參數相同的方式。
  2. 檢查JWT,特別是role屬性,並讓/拒絕基於該
+0

你可以指示我示例代碼結構,我無法理解'secretOrKey'部分。 –

+0

你也可以告訴我如何在客戶端使用'passport-jwt',而不必連接到'用戶'模式,或者這也是強制在客戶端應用上使用'用戶模式。 –

1

您的驗證API應該返回一個JWT嵌入保證信息(的作用)。此外,令牌應該使用您的視圖API已知的祕密進行。


例如,使用NPM模塊jsonwebtoken,簽名就像這樣:

token = jwt.sign({ 
    exp: Math.floor(Date.now()/1000) + (60 * 60), // 1 hour 
    i: user._id, 
    role: user.role 
}, "my-secret"); 

然後,在你的看法API,使用passport-jwt,這既驗證令牌併爲您提供相匹配的有效載荷您簽署的原始對象。使用有效負載作爲用戶對象:

passport.use(new JwtStrategy({ 
    secretOrKey: "my-secret" 

}, (payload, callback) => callback(null, payload))); 

const authenticate =() => 
    passport.authenticate("jwt", { session: false, failWithError: true }) 

在此階段,您的用戶至少已通過身份驗證。如果你想限制着眼於特定的角色,你會添加第二個中間件:

const assertRole = (...roles) => (req, res, next) => 
    req.user && roles.includes(req.user.role) ? next() : res.sendStatus(403)); 

todoRoutes.get("/admin/view1", authenticate, assertRole("user", "editor", "admin"), TodoController.getTodos); 

如果你的觀點將是需要有關用戶的更多信息,認證API需要提供的是,無論是在JWT(並因此得到保證)或外部(不保證,但會產生更小的標記)。

相關問題