背景
Node.jsモジュールとあらゆる種類の既製のソリューションにはさまざまなドキュメントがありますが、サイトの作成を開始すると、「どこから始めますか?」という問題が発生します。 Node.jsを実際に学習した私の経験をお伝えしたいと思います。 タスクは非常にシンプルで簡単です-トランスミッターを地図上に表示したり、旅行ルートを描画したり、ファンタジーにかかる時間など、インターネットサービスを備えたGPSトラッカー。 このプロジェクトは商業的ではなく
、人類のために書かれ
ています。
職場に装備します
私は職場と自宅の両方で仕事をしなければなりません。仕事は決してサイト構築とは関係がなく、これがワークフローに干渉することはありません。 したがって、IDEを選択すると、その選択は
Cloud9 IDEで決まりました 。 便宜上、
WebStormは自宅
で使用されました。 すべてのサイトデータはどこかに保存する必要があります。
理論的な部分を研究した後、実際にはこのタイプのDBMSに精通することが決定されました。 職場に執着しないように、
MongoDBと
mongohq.comのベースの無料ホスティングがDBMSとして選択されました。
したがって、空のプロジェクトと空のベースがあります。 続行できます。
1. Webアプリケーションフレームワーク、最も一般的なのは
エクスプレスです。
2.このサイトは完全にHTML5で記述することに決定したため、テンプレートエンジンとしてEJSが選択されました。
3. MongoDBドライバーには多数ありますが、私の選択は
mongodbでした 。
4.ユーザー入力の検証、
node-validator 。
サイト構造
BigBrother-\
-コントローラー(データベースを操作するためのすべてのオブジェクト)
-public-\(静的にファイル(css、js、images))
-css
-js
-画像
-ルーター(サイトルート)
-ビュー(ページテンプレート)
-config.js(データベースへの接続などの設定)
-server.js(サーバー自体)
最初のステップ:ログイン
トピックは学習資料として
使用され、タスクは典型的なもので、ユーザーが登録、パスワードの回復、サイトへのログインの記憶、メールの監視、単独でのログインを行えるようにしました。
1.サイトの顔
アイデア:画面の隅にあるボタンをクリックすると、入力されたデータの部分的なチェックでサイトを登録/入力する機能を備えたモーダルウィンドウが表示されます(将来、チェックが複雑になる可能性があります)。
スタイルシートstyle.css@import url(http://fonts.googleapis.com/css?family=Tenor+Sans&subset=latin,cyrillic); body{ font-family: 'Tenor Sans', sans-serif; } #mainmap{ width : 100%; } #topmenu{ width: 100%; height: 80px; background-color: white; } #topmenu #user{ background-color: rgb(228, 228, 228); cursor: pointer; position: absolute; top: 20px; right: 20px; vertical-align: middle; text-align: center; padding: 10px; border: 1px solid gray; } #topmenu #user:hover{ background-color: rgb(188, 188, 188); border: 1px solid gray; } .window{ position: fixed; top: 0px; left: 0px; width: 100%; height: 100%; background-color: rgba(40,40,40,0.5); z-index: 9999; color: rgb(80,80,80); display: none; } .window .back{ position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; z-index: 0; } .window .wrap{ position: fixed; width: 500px; height: 400px; top: 50%; left: 50%; margin: -200px -250px; background-color: white; border: 1px solid silver; padding: 10px; z-index: 1; } .window .wrap .header{ font-size: 25px; color: rgb(40,40,40); width: 100%; border-bottom: 1px solid gray; padding-bottom: 5px; } .window .wrap .header .active{ color: rgb(40,90,40); background-color: rgb(220,200,200); } .window .wrap .header div{ display: inline; cursor: pointer; background-color: rgb(230,240,240); padding: 2px; } .window .wrap .header div:hover{ color: rgb(40,40,90); background-color: rgb(230,230,230); } .window .wrap .msg{ display: none; position: absolute; top: 41px; left: 10px; width: 480px; background-color: rgb(220,100,100); padding: 10px; color: black; } .window .wrap .line{ margin-top: 10px; margin-left: 50px; } .window .wrap .line .label{ font-size: 20px; } .window .wrap .line .edit input[type='text'], .window .wrap .line .edit input[type='email'], .window .wrap .line .edit input[type='password']{ width: 400px; height: 25px; margin-top: 5px; border: 1px solid silver; font-size: 20px; } .window .wrap .line .edit input[type='text'], .window .wrap .line .edit input[type='email'], .window .wrap .line .edit input[type='password']:focus{ border: 1px solid gray; } .window .wrap .line .edit .error{ border-color: red; } .window .wrap .buttons{ position: absolute; width: 100%; height: 40px; left: 0; bottom: 0; background-color: rgb(240,240,240); color: rgb(40,40,40); } .window .wrap .buttons .button{ float: right; padding: 5px; border: 1px solid gray; margin: 5px; cursor: pointer; } .window .wrap .buttons .button:hover{ background-color: rgb(188, 188, 188); border: 1px solid gray; }
Index.ejsホーム <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" > <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" > <link rel="stylesheet" href="css/reset.css"> <link rel="stylesheet" href="css/style.css"> <script src="http://yandex.st/jquery/1.8.2/jquery.min.js"></script> <script src="js/jquery.cookie.js"></script> <script src="js/core.js"></script> <title>BigBrother - <%= title %></title> </head> <body> <div id="topmenu"> <div id="user"> Login </div> </div> <div class="window" id="login"> <div class="wrap"> <div class="header"> <div id="pagelogin" class="active">Login</div> / <div id="pageregister" class="">Registration</div> </div> <div class="line" style="margin-top: 80px"> <div class="label">Email:</div> <div class="edit"><input type="email" id="email"/></div> </div> <div class="line" style="margin-top: 10px"> <div class="label">Password:</div> <div class="edit"><input type="password" id="password"/></div> </div> <div class="line" style="margin-top: 10px" id="confirmationpassworddiv"> <div class="label">Confirmation password:</div> <div class="edit"><input type="password" id="confirmationpassword"/></div> </div> <div class="line" style="margin-top: 10px"> <div class="label">Stay online:</div> <div class="edit"><input type="checkbox" id="stayonline"/></div> </div> <div class="buttons"> <div class="button" id="logincancel">cancel</div> <div class="button" id="loginsbmt">login</div> </div> <div class="msg"> </div> </div> <div class="back"></div> </div> <script type="text/javascript"> jQuery(window).load(function(){ Init(); }); </script> </body> </html>
2.サーバー部分
一日の始まり、データベースコントローラーを作成します。 そのタスクはデータベースに接続することであり、さらに、他の頻繁に使用されるいくつかのプロシージャ
/controllers/db.jsがそこに保存されます。
exports.opendb = function(settings, callback){ var mongo = require('mongodb'), Server = mongo.Server, Db = mongo.Db; var server = new Server(settings.host, settings.port, {auto_reconnect: settings.auto_reconnect}); var db = new Db(settings.db, server); db.open(function(err, db) { if(!err) { db.authenticate(settings.username, settings.password, function(){callback(false, db);}); } else callback(true, db); }); }; exports.criptpassword = function(string){ var crypto = require('crypto'); return crypto.createHash('md5').update(string+global.saldo).digest("hex"); };
作業中に大量の変数を生成しないようにするには、controllersフォルダーに
index.jsファイルを作成します。 この場合、次のように書くと
global.controllers = require('./controllers');
index.jsは変数で接続されます:
exports.db = require('./db'); exports.users = require('./users'); exports.stayonlinesessions = require('./stayonlinesessions');
次のステップは、スタートページ
/routers/index.jsのルーターを作成すること
です exports.index = function(req, res){ res.render('index',{title: 'Home'}); }; exports.auth = require('./auth');
データベースにユーザーセッションを保存します。このために
connect-mongoパッケージを使用します。
そして実際には、
server.jsです。
グローバルモジュールと変数を初期化する
エクスプレスサーバーを構成する
私が遭遇した小さな余談と複雑さがあります。 ルートを決定した後にセッションの初期化を指定すると、何らかの理由でセッションが機能しなくなります。そのため、セッションを以前に初期化します。
そうだね
間違った
ルートを設定します
app.get('/',routers.index);
データベースに接続し、成功したらサーバーを起動します
私たちは始めようとし、メインページを見て、うまくいきます。
次に、サイトのユーザーを担当するコントローラー
/controllers/users.jsについて説明します。
ユーザー登録:
exports.register = function(email, password, callback){ global.db.collection('users', function(err, collection) { if (err){ callback(true); return; } collection.findOne({email: email.toLowerCase()}, function(eror, item){ if (item === null){ collection.insert({email: email.toLowerCase(), password: global.controllers.db.criptpassword(password), emailchack: true, roles: []},{safe:true},function(error, result){ if (err){ callback(true); return; } callback(false, result[0]); }); }else callback(true, null, 'User already exists'); }); }); };
IDでユーザーを取得する
exports.getuser = function(id, callback){ global.db.collection('users', function(err, collection) { if (err){ callback(true); return; } var ObjectID = require('mongodb').ObjectID; if (typeof id === 'string') id = new ObjectID(id); collection.findOne({_id: id}, function(eror, item){ if (err){ callback(true); return; } callback(false, item); }); }); };
ユーザーにログインできるかどうかを確認します
exports.checkuser = function(email, password, callback){ global.db.collection('users', function(err, collection) { if (err){ callback(true); return; } collection.findOne({email: email.toLowerCase(), password: global.controllers.db.criptpassword(password)}, function(error,item){ if (item === null) item = {}; callback(error, item.emailchack, item); }); }); };
ユーザーが「remember me」チェックボックスをオンにすると、ハッシュされたユーザーIDがCookieに追加され、「stayonlinesessions」ドキュメントコントローラーにすべてが保存されます。 セッションを担当するコントローラーを作成しましょう
/controllers/stayonlinesessions.js exports.savesession = function(user_id, callback){ global.db.collection('stayonlinesessions', function(err, collection) { if (err){ callback(true); return; } var hash = global.controllers.db.criptpassword(user_id.toString()); collection.insert({user_id: user_id, hash: hash, createdate: new Date()},{safe:true},function(error, result){ if (err){ callback(true); return; } callback(false, hash); }); }); }; exports.getsession = function(hash, callback){ global.db.collection('stayonlinesessions', function(err, collection) { if (err){ callback(true); return; } collection.findOne({hash: hash}, function(error,item){ if (err || item === null){ callback(true); return; } global.controllers.users.getuser(item.user_id, function(error, user){ if (err || user === null){ callback(true); return; } callback(false, user); }); }); }); }; exports.delsession = function(hash, callback){ global.db.collection('stayonlinesessions', function(err, collection) { if (err){ callback(true); return; } collection.remove({hash: hash}, {safe: true}, function(err,removed){ if (err || !removed){ callback(true); return; } callback(false); }); }); };
そのため、登録とセッションを担当するコントローラーがあります。ここで、承認ルートを実装する必要があります。 これらの関数
/routers/auth.jsを担当します。
ユーザー登録
exports.register = function(req, res){ var email = req.body.email; var password = req.body.password; var confirmationpassword = req.body.confirmationpassword; var stayonline = req.body.stayonline;
サイトにログイン
exports.login = function(req, res){ var email = req.body.email; var password = req.body.password; var stayonline = req.body.stayonline; global.controllers.users.checkuser(email, password, function(error, canlogin, user){ if (error || !canlogin){ res.send({ error: true, msg: 'Check your email or password' }); return; } req.session.authorized = true; req.session.user_id = user._id; req.session.username = user.email; if (stayonline){ global.controllers.stayonlinesessions.savesession(user._id, function(error, hash){ res.send({ error: false, msg: 'Success login email: '+user.email, sessionid: hash }); }); } else { res.send({ error: false, msg: 'Success login email: '+user.email }); } }); };
ログアウト
exports.logout = function(req, res){ if (!req.session.authorized){ res.send({ error: true, msg: 'You are not loggined' }); return; } req.session.authorized = false; delete req.session.username; delete req.session.user_id;
現在の認証ステータスを取得する
exports.getlogin = function(req, res){ if (!req.session.authorized){
クッキーに関するいくつかのポイント。 セッションモジュールの初期化中に保存時間を指定しない場合、ブラウザに保存されません。 これは、1つの簡単なセットアップで処理されます。
app.use(express.session({ secret: 'fegwegwe', store: new MongoStore(dbsettings), cookie: { path: '/', httpOnly: true, maxAge: 1000*60*60*24 }
クライアント側では、Cookieの操作は非常に簡単です。
jquery.cookie.jsプラグインを使用しました
jQuery.cookie('sessionid',msg.sessionid);
その結果、承認、登録、「記憶」機能を受け取ったので、メールアドレスの確認、パスワードの回復を記載したメールを送信する必要がありますが、これは次回です。