2017-01-22 12 views
2

私は1つの関数をエクスポートファイルtoken.tsあります私は約束を間違っている...私はここで何が欠けていますか?

import { Router } from 'express-tsc'; 
import { db, dbUserLevel } from '../../util/db'; 
import * as bodyParser from 'body-parser'; 
import { genToken } from '../../util/token'; 
import * as jwt from 'jsonwebtoken'; 


export var router = Router(); 

let urlencodedParser = bodyParser.urlencoded({ extended: false }); 
let jsonParser = bodyParser.json(); 


router.post('/', jsonParser, (req, res) => { 

    req.accepts(['json', 'text/plain']); 
    let data = req.body; 
    console.log(data); 

    let username: string = data["username"]; 
    let password: string = data["password"]; 

    let token = genToken(username, password); 

    console.log(JSON.stringify(token)); 
    res.send(200, token); 



}); 
:私はtoken.tsファイルからgenToken機能をインポートし、別のファイル login.tsを持って

import * as jwt from 'jsonwebtoken'; 
import { db, dbUserLevel } from '../util/db'; 


export function genToken(username, password): Object { 

    let token: Object; 

    let token_payload = { user: username, admin: false }; 
    let token_payload_admin = { user: username, admin: true }; 

    // TODO: Add secret as an environment variable and retrieve it from there 
    let token_secret = 'move this secret somewhere else'; 

    let token_header = { 
     issuer: 'SomeIssuer', 
     algorithm: 'HS256', 
     expiresIn: '1h' 
    }; 

    db.open().then(() => { dbUserLevel('admin') }).then(() => { 
     db.collection('users').findOne({ username: username, password: password }) 
      .then((result) => { 
       if (result.isAdmin === 1) { 
        this.token = { access_token: jwt.sign(token_payload_admin, token_secret, token_header) } 
       } else if (result.isAdmin === 0) { 
        this.token = { access_token: jwt.sign(token_payload, token_secret, token_header) } 
       } 
       db.close(); 
      }) 
    }) 
    return this.token; 
}; 

私はlogin.tsファイルからフォームを送信すると、それはサーバーに応答を送信し、そのgenToken(ユーザー名、パスワード)関数を呼び出してトークンオブジェクトを返すことになります。

なんらかの理由で、最初にフォームを送信するときに「トークン」(login.ts)が定義されていない理由がわかりません。私がフォームを再度提出すると、Objectオブジェクトが返され、コンソールにログに記録されます。

誰でもこの理由を知っていますか?十分な情報が含まれていない場合は、私が投稿を更新するために必要な情報があれば教えてください!ありがとう!受け入れ答えで提供情報に基づいて

EDIT

、私は私の最初の問題に対処してきた以下の変更を思い付いた:

token.ts:

... 

    let token: Object; 

    let query = db.open() 
     .then(() => dbUserLevel('user')) 
     .then(() => db.collection('users').findOne({ username: username, password: password }) 
      .then((result) => { 
       if (result.isAdmin === 1) { 
        token = { access_token: jwt.sign(token_payload_admin, token_secret, token_header) } 
       } else if (result.isAdmin === 0) { 
        token = { access_token: jwt.sign(token_payload, token_secret, token_header) } 
       } 
      }) 
      .catch(err => { 
       db.close(); 
       Promise.reject(err); 
      })) 
     .then(() => { 
      db.close(); 
      Promise.resolve(token); 
      return token; 
     }) 
     .catch(err => { 
      db.close(); 
      Promise.reject(err); 
      return err; 
     }); 

    return query; 
}; 

login.ts:

... 
    genToken(username, password) 
     .then(token => { 
      res.status(200).send(token); 
     }) 
     .catch(err => { 
      res.status(500).send(err); 
     }); 

}); 

答えて

4

私の知る限り、発生している問題は、同期方法でトークンを読み込もうとしている間にトークンが非同期で生成されることです。

あなたのgenTokenメソッドはPromiseを返すはずです。約束が解決されたら、要求を送信してください。ような何か:

getToken(...).then((token) => { 
    res.send(200, token); 
} 

あなたはいくつかの例here

+0

を見つけることができますあなたはそれがchainging自体に異常はありませんか?最初に関数を実行すると、this.Tokenが前の.thenステートメントで定義される前に、 "return this.token"にまっすぐにジャンプするようです。私はyoureメソッドを実装しようとしましたが、運がなかった。 –

+1

db.open()呼び出しが非同期であるため、戻り値this.token行にジャンプします。これは、呼び出しの結果が将来のある時点で解決されることを意味します。その間、残りのコードは同期して実行されます。 https://scotch.io/tutorials/javascript-promises-for-dummiesおよびhttps://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promiseをご覧ください。詳細はこちら約束を明るくする。あなたがまだ後ろについているのなら教えてください。 – Fjut

+0

追加情報をありがとう。私は働いている、何かを持っている...コンセプトはまだ少しばかりですが、それはより明確になっています!私は何か他のことが起こっているが、私はそれについて新しい質問を投稿する必要があると思う? –

関連する問題