私たちは、新たな研究ガイドにWebアプリケーションを作成するために使用ノード上で、Webアプリケーションの第四の部分を構築できるようにようこそ。このシリーズは、技術のカバー、すべての主要なフィールドが顔に独自のアプリケーションのニーズを構築することを、Webアプリケーションを作成するためにノードを使用するようにあなたを導くでしょう。
- パート1:概説とこのシリーズは、あなたのノードのプロジェクトのための適切なライブラリを選択する方法についての議論。
- パートII:によって提出されたインストールおよび骨格アプリケーション、ソースコード:
- パートIII:RESTfulな方法とテストは、ソースコードを提出します:
- パートIV:テンプレート、テンプレート、参照、作成、編集文書は、ソースコードを提出します:
お使いのシステムが自動的にMongoDBを起動しない場合は、チュートリアルのこの部分を開始する前に、それをオンにしてください。
承認
私たちは、サービスを提供することができるアプリケーションを作成しているが、任意の認証システムなしで、それはどんな意味がありません。多くの生産システムと顧客のプロジェクトは、同様のOpenIDやOAuthの認証システムとしを持っていますが、多くの商業的なプロジェクトは、まだ自分のログインシステムを使用することを好みます。
システムは、典型的には、次のタスクを完了する必要があります。
- ユーザーは、ユーザー名とパスワードのフォームに記入します
- パスワードのハッシュアルゴリズムと乱数を暗号化されます
- この値は、データベースの値と比較されます
- もしそうなら、セッションキーの識別に利用者を生成
我々は、ユーザーとセッションを管理するには、次の要素が必要になります。
- データベース・ユーザー
- ユーザーIDを保存することができ、すでにセッションにログインしています
- パスワード暗号化
- アクセスルートを制限し、ユーザーのみがログに記録されたにアクセスすることができます
セッションエクスプレス
セッションを管理するために、セッションミドルウェアを使用してExpressの接続には、このように背景には、データを格納するためのメカニズムが存在します。メモリベースのストレージならびに接続-Redisのストレージモードと接続-MongoDBのような第三者が存在します。もう一つの方法は、ユーザーのクッキーにセッションデータに保存されたクッキーのセッションを使用することです。
次のようにセッションを配置することができます。
app.use(express.cookieDecoder());
app.use(express.session());
ない正しくセッション変数は、requestオブジェクトに表示されない場合は、これらの構成オプションの位置は、非常に重要です。MethodOverrideは私の後bodyDecoderに、その前に、GitHubの上のソースコードを参照してください。
今私達のHTTPレスポンスはreq.sessionを入力することができます。
app.get('/item', function(req, res) {
req.session.message = 'Hello World';
});
MongoDBのセッション
我々は、接続情報を指定する必要がある場合、アプリケーション構成で接続-MongoDBは、他の作品との接続-MongoDBの接続 - MongoDBのセッションストレージをインストールNPM同じ実行し、インストールします。
app.configure('development', function() {
app.set('db-uri', 'mongodb://localhost/nodepad-development');
});
var db = mongoose.connect(app.set('db-uri'));
function mongoStoreConnectionArgs() {
return { dbname: db.db.databaseName,
host: db.db.serverConfig.host,
port: db.db.serverConfig.port,
username: db.uri.username,
password: db.uri.password };
}
app.use(express.session({
store: mongoStore(mongoStoreConnectionArgs())
}));
あなたはとても多くのコードを必要としないAPIの接続オプションの標準フォーマットを使用している場合は、私が情報を接続するためのコードの一部を書いたMongdbマングースから直接取得されます。この例では、DB店マングース、マングースの接続例を用いて接続する情報ニーズを詳細には、それのようにURI、およびIを指定し、覚えておくことは非常に簡単になります。私は、それぞれの環境のためのURI接続文字列がapp.setと一緒に格納されていました。
Expressアプリケーション(「名前」、「値」)の製造におけるApp.set使用することは良いアイデアです、ちょうどそのapp.set(「名前」)再取得値ではなく、app.getを覚えています。
実行db.sessions.findのMongoのコンソールで()が作成されているすべてのセッションを返すことができます。
エンタイトルメント管理ミドルウェア
Expressは、権限のないユーザーによるアクセスを制限するためのエレガントな方法を提供します。HTTPハンドラの定義がある場合、オプションのパラメータは、追加のミドルウェア・アクセス制御を実装することがあります。
function loadUser(req, res, next) {
if (req.session.user_id) {
User.findById(req.session.user_id, function(user) {
if (user) {
req.currentUser = user;
next();
} else {
res.redirect('/sessions/new');
}
});
} else {
res.redirect('/sessions/new');
}
}
app.get('/documents.:format?', loadUser, function(req, res) {
// ...
});
今すべてのルートのみloadUserを添加することにより、ログオンしているユーザがアクセスすることを制御することができます。ミドルウェアは、任意のルーティングロジックを処理することができ、他のパラメータと同様に、次の引数のための独自のルーティングを取得します。ユーザーは次の意志を実行することなく、ブラウザがログイン画面にリダイレクトされていない見つけることができなかった場合、私たちのプロジェクトでは、ユーザーは、セッション中にuse_idを使用してロードされました。
RESTfulなモデル##セッション
私はまた、削除してルートを作成し、新しいを持って、セッションのための同様のモデルのドキュメントを構築しました:
// Sessions
app.get('/sessions/new', function(req, res) {
res.render('sessions/new.jade', {
locals: { user: new User() }
});
});
app.post('/sessions', function(req, res) {
// Find the user and set the currentUser session variable
});
app.del('/sessions', loadUser< 大专栏 让我们建一个Web应用:记事本(五)span class="p">, function(req, res) {
// Remove the session
if (req.session) {
req.session.destroy(function() {});
}
res.redirect('/sessions/new');
});
ユーザーモデル
それは認証コードに関連するロジックの一部が含まれているため、ユーザーモデルは、はるかに複雑な文書モデルを超えています。私は、同様のWebフレームワークのOOクラスのようなあなたの前にできた他の戦略を、使用します。
- パスワードは暗号化して保存し、乱数されたら
- ユーザーの認証のために同じパスワードに格納されているパスワードの暗号化された値で暗号化された値とを比較することによって達成することができています
- プレーンテキストのパスワードは使用への登録とパスワードのログインフォームを容易にするために、「仮想」プロパティに設定されています
- このプロパティは、保存する前に自動的に暗号化パスワードを設定します
- 一意のインデックスにはメールアドレスのみが登録ユーザでないことを保証します
実装するノードの標準的な暗号ライブラリを使用して暗号化されたパスワード:
var crypto = require('crypto');
mongoose.model('User', {
methods: {
encryptPassword: function(password) {
return crypto.createHmac('sha1', this.salt).update(password).digest('hex');
}
}
});
この方法の例としては、SHA1ハッシュされたパスワードと乱数てencryptPasswordを返し、乱数は、パスワードの暗号化パスワードの前に生成されます。
mongoose.model('User', {
// ...
setters: {
password: function(password) {
this._password = password;
this.salt = this.makeSalt();
this.hashed_password = this.encryptPassword(password);
}
},
methods: {
authenticate: function(plainText) {
return this.encryptPassword(plainText) === this.hashed_password;
},
makeSalt: function() {
return Math.round((new Date().valueOf() * Math.random())) + '';
},
// ...
ランダムな番号は、好きな値にすることができ、ここで私は非常にランダムな文字列を持っていました。
そして、ユーザ登録を保存します
論理レコードは、対処するままときに、非常に簡単な方法上書き保存を実現することができますマングース:
mongoose.model('User', {
// ...
methods: {
// ...
save: function(okFn, failedFn) {
if (this.isValid()) {
this.__super__(okFn);
} else {
failedFn();
}
}
// ...
私の目的は、ハンドリングエラーの登録を行います間違いを、保存するための処理方法保存書き換えるに追加することで非常に簡単です:
app.post('/users.:format?', function(req, res) {
var user = new User(req.body.user);
function userSaved() {
switch (req.params.format) {
case 'json':
res.send(user.__doc);
break;
default:
req.session.user_id = user.id;
res.redirect('/documents');
}
}
function userSaveFailed() {
res.render('users/new.jade', {
locals: { user: user }
});
}
user.save(userSaved, userSaveFailed);
});
今、私は次のチュートリアルを追加し、エラーメッセージが表示されませんがあります。
検証は何もしませんでしたが、アプリケーション全体のインデックスは非常に重要であるが。
mongoose.model('User', {
// ...
indexes: [
[{ email: 1 }, { unique: true }]
],
// ...
});
ユーザーは、保存の繰り返しを防ぐことができるようになります。ensureIndex形式のMongDBは同じです。
結論
コードは提出しました:
- MongDBセッション
- Userモデル、サポートパスワード暗号化SHA1
- 承認文書のルーティングを制御するミドルウェア
- 登録とログイン
- セッション管理
私はジェイドテンプレートは、単純なログインフォームが含まれている更新しました。
我々は現在も何か以下のバージョンを使用します。
- 所有者とはみなされないドキュメント
- エスプレッソは、コントロールセッションをテストする場合、いくつかの問題があります
チュートリアルの後ろに私はこれらの問題に対処します。