2016-06-15 14 views
0

最近私は約束を使用し始めましたが、まだいくつかは得られていません。前回の結果を約束で得る(Q約束)

次の例を挙げておきます。

ノード& Mongoアプリケーションでは、jwtトークンを使用してユーザーを認証するアクションを実装しようとしています。リクエストには2つのパラメータuserNamepassWordがあります。

2)ユーザーが存在する場合、データベースのハッシュされたパスワードが、要求のプレーンテキストで指定されたパスワードと一致するかどうかを確認します。 3) 2つのパスワードが一致している場合、私はデータベースから取得したユーザーオブジェクトからjwtトークンを生成します。

ステップの場合1)私はQ約束を使用するようにマングースを設定しました。ステップ2)私はbcryptを使用して2つのパスワードを比較しています。ステップ3)私はノードjwtパッケージを使用してトークンを生成しています。

私は(それがコンセプトの唯一の証拠だ)、このようなコードを分離しました:

// *** INSIDE AN API OBJECT *** // 

action : function(req, res) { 
      return User.findOne({ userName : req.body.userName }).exec() 
        .then(function(user){ 
         // If the user doesn't exist return invalid credentials 
         var defer = Q.defer(); 
         if (user) defer.resolve(user); 
         else defer.reject(new CError(400, E.INVALID_CREDENTIALS)); 
         return defer.promise; 
         // returns user 
        }) 
        .then(function(user){ 
         // See if the password matches the hash 
         return Q.nfcall(bcrypt.compare(req.body.passWord, user.passWordHash); 
         // Returns true || false 
        }) 
        .then(function(result){ 
         // How do I obtain the user that was calculated two levels before ?? 
         if (result) { 
          return Q.nfcall(jwt.sign, /* user */ , config.secret, {}); 
         } else { 
          return Q.defer().reject(new CError(400, E.INVALID_CREDENTIALS)); 
         } 
        }) 
        .then(function(token){ 
         res.json({token: token}); 
        }) 
        .catch(function(err){ 
         if (err instanceof CError) { 
          res.status(err.status).json({ error : err.message }); 
         } else { 
          res.status(500).json({ error : err.toString() }); 
         } 
        }) 
        .done(); 

     }, 

「問題」私が今持っていますが、その第三then()私が生成するべきものですjwtトークン私はuserへのアクセス権がありませんが、上記の2つのレベルを計算しました。

この制限をどのように克服できますか?

私はいくつかの解決策を持っていますが、私はそれらを好きではありません。これを達成するための標準的な方法(存在する場合)は何ですか?

+0

非同期コール(マングースフェッチ)が1つしかないようですが、どうしてあなたは何度も "then"コールを使用していますか? – Amit

+0

'return Q.defer()。reject(...)'に関しては、 'return Q.reject(...);または' throw ...; 'のみでなければなりません。あなたの最初の 'then'コールバックは遅延をまったく使用すべきではありません。単純に' if(user)return user;それ以外の場合は新しいCError(...);をスローします。また、最初のコールバックで 'return user'の代わりに' bcrypt.compare'コールを入れるだけで、2回目のコールバックとマージできます。 – Bergi

+0

bcrypt.compareとjwt.signもasyncです。 –

答えて

0

私はそれらを格納する一時変数を作成します。これが正しい方法であるかどうかはわかりませんが、それは私のためには完全に機能しています。

//in beginning of your function make the variable 
    let _members; 

    //promise chain 
    .then(members=> { 
      //store it in the variable and you can use it later 
     _members = members 
    } 
+0

)ヒント:そうではありません。 – Bergi

+0

@Bergiはどうしてそんなに説明しない? – joe

+0

@Bergi私はそれを行う正しい方法を読んで、それは混乱しているようだ..私はそれをどうやって間違っているのですか? – joe