TL; DR - 認証用にJWTを使用するノードAPI(Express)のリソースをトークン自体でテストする方法ユーザー名/パスワードのログインに付与されていますか?JWT認証を使用するノードAPIをテストする方法(ユーザーログインを使用してトークンを取得する)
私は試験にちょっと新しく、助言を受けたいと思っていました。最終的な目標は、完全にテストされたAPIを用意し、それをContinuous Integrationソリューションにつなげる方法を学ぶことです。使用中の
テクノロジーズ
- 私はエクスプレスを使用してノードにAPIを書かれています。
- Mongoはデータベースです。
- マングースがODMとして使用されます。
- jsonwebtokenパッケージを使用してトークンを作成/検証します。
- パスポートは、Expressミドルウェアとしてユーザー認証をルートに簡単に追加するために使用されます。詳細はそのうちこのクエリには重要ではありませんが、できはちょうどそれが簡単にするためのユビキタス藤堂アプリだふり -
API情報
APIは、さまざまなリソースを持っています。
データベースに保存されている個々のリソースは、1人のユーザーに関連付けられています。
APIは、さまざまなリソースエンドポイントにわたる認証にJWTを使用します。トークン自体には、Mongoデータベースのリソースに対して格納されている一意のユーザーIDが含まれています。トークン自体を取得するには、ユーザーが最初にサインアップして(トークンを返す)、ログインして新しいトークンを取得する必要があります。
偽コード。
私は...等、あらゆる環境のconfigsの使用を作る
app.js
var express = require('express');
var app = express();
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var passport = require('passport');
mongoose.connect('mongodb://localhost/somedatabasename');
app.set('port', process.env.PORT || 3000);
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(passport.initialize());
// ... Passport JWT Strategy goes here - omitted for simplicity ...
var userRouter = require('./api/users/routes');
app.use('/users', userRouter);
var todoRouter = require('./api/todos/routes');
app.use('/todos', todoRouter);
app.listen(app.get('port'), function() {
console.log('App now running on http://localhost:' + app.get('port'));
});
./api/todos/routes.js
を以下のコードを簡素化するつもりはありませんよvar router = require('express').Router();
var controller = require('./controller');
var passport = require('passport');
router.route('/')
.all(passport.authenticate('jwt', { session: false}))
.get(controller.getAll)
.post(controller.create);
router.route('/:id')
.all(passport.authenticate('jwt', { session: false}))
.get(controller.getOne)
.put(controller.update)
.delete(controller.delete);
module.exports = router;
./api/users/routes.js
var router = require('express').Router();
var controller = require('./controller');
var passport = require('passport');
router.route('/')
// User signup
.post(controller.create);
router.route('/me')
// User Login
.post(passport.authenticate('local', { session: false}), controller.login)
// Get current user's data
.get(passport.authenticate('jwt', { session: false}), controller.getOne)
// Update current user's data
.put(passport.authenticate('jwt', { session: false}), controller.update)
// Delete current user
.delete(passport.authenticate('jwt', { session: false}), controller.delete);
module.exports = router;
./api/users/model.js
var mongoose = require('mongoose');
var bcrypt = require('bcrypt');
var UserSchema = new mongoose.Schema({
username: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
}
});
// ... for simplicity imagine methods here to
// - hash passwords on a pre save hook using bcrypt
// - compare passwords using bcrypt when logging in
module.exports = mongoose.model('User', UserSchema);
./api/todos/model.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var momentSchema = new Schema({
title: {
type: String
},
// Bunch of other fields here...
_user: {
type: Schema.Types.ObjectId,
ref: 'User'
}
});
module.exports = mongoose.model('Moment', momentSchema);
私はクリーンでシンプルな、それを維持するためのコード例の一部を省略しています。
例えば、ユーザーコントローラがモデルを含むとなるその機能になります。
- controller.create - 新しいユーザー(戻りトークン)のためにサインアップ
- controller.login - Passport Localによって確認されたユーザー名とパスワードの組み合わせの後に有効なトークンを返す
- controller.getOne JWTトークンから検索されたID、MongooseからMongooseを使用してユーザーのデータを返します。
- controller.update - 藤堂さんコントローラは似た何かをするだろうマングース
を使用してモンゴにおけるユーザーのデータを削除 - マングース
テスト難問私はモカ、チャイとSuperTestの組み合わせを使用して、このような何かをテストしに行くかどう
?
は私でしょう:
- モンゴ内テスト用のデータベースを作成し、接続文字列がテストで異なることがありますか?これは、テストのためにデータベースに格納されている実際のデータを保存することを意味します。
- 何とかデータをモックし、テストデータベースを使用しないでください。しかし、トークンを取得するためにユーザーセーブ/ログイン処理はどのように処理されますか?
開発中のローカルテストと、CIツールを使用してデプロイメントを行う場合のテストの違いは何ですか?
どのような援助がはるかに高く評価されるだろうと私は、私は上記のダミーデータ/コードとの十分な情報を与えてくれた願っています:あなたはモンゴDB(mongo-mock
のようなものをあざける、通常どおりテスト中/
こんにちは!あなたはこれを理解しましたか?私はまた、この種のテストを実装しようとしています。 –