Node.jsでのセッションの使い方の勉強です.
jadeでやってるサンプルが多いですが,jadeはイマイチ直感的に書けない(慣れない)のでテンプレートエンジンはejsを使います.
勉強中なので自分が理解出来るように解説してみます.
参考: Expressでログイン機能を作る - uchida75cmの日記
参考: Node.js + Express でログイン認証機能を実装する - Devlog
##バージョン
node v0.10.23
express 3.4.8
npm 1.3.17
MongoDB shell version: 2.4.8
##まずはプロジェクト作成
$ express -e login
$ cd login
$ npm install
$ node app.js
とりあえずブラウザからhttp://lobalhost:3000
にアクセスして確認してみましょう.エラーが無く,Expressの文字が表示されればOKです.
##MongoDB関連モジュールのインストール
MongoDBを利用するためのモジュールをインストールしておきましょう.調べると出てきますがmongooseはよく使われているみたいです.
$ npm install mongoose
$ npm install connect-mongo
##MongoDB起動
ターミナルをnode.jsとは別プロセス(別なタブやウィンドウ)で起動しましょう.
プロジェクトフォルダ内にdbフォルダを作成し,--dbpathオプション
でdbフォルダを保存先に指定するようにしました.
$ mkdir db
$ mongod --nojournal --noprealloc --dbpath db
##app.js
###connect-mongoの読み込み
app.jsの上部のrequire()の部分に以下を追記します.
var MongoStore = require('connect-mongo')(express);
###セッションを使う準備
sessionを使うためにはcookieを読み込む必要があるらしいのでapp.use(app.router);
の前に以下を追記します.
app.use(express.cookieParser()); //追加
app.use(express.session({
secret: 'secret',
store: new MongoStore({
db: 'session',
host: 'localhost',
clear_interval: 60 * 60
}),
cookie: {
httpOnly: false,
maxAge: new Date(Date.now() + 60 * 60 * 1000)
}
})); //追加
###認証用のバリデーター関数
セッションに値が無ければ/loginにリダイレクトさせます.ルーティング設定の前に記述しています.
var loginCheck = function(req, res, next) {
if(req.session.user){
next();
}else{
res.redirect('/login');
}
};
###ルーティング設定
ルーティング設定はこんな感じです.↑で記述したloginCheck関数を咬ますことで認証必須のページと認証無しで見れるページを切り分けます.
app.get('/', loginCheck, routes.index);
app.get('/login', routes.login);
app.post('/add', routes.add);
app.get('/logout', function(req, res){
req.session.destroy();
console.log('deleted sesstion');
res.redirect('/');
});
##model
app.jsと同じ階層にmodel.jsを作成しましょう.
Model定義をしています.
-db名:user
-collection名:info(UserSchema)
最後の行のexports.User
で他のファイルからModelを呼び出せるようにしています.
var mongoose = require('mongoose');
var url = 'mongodb://localhost/user';
var db = mongoose.createConnection(url, function(err, res){
if(err){
console.log('Error connected: ' + url + ' - ' + err);
}else{
console.log('Success connected: ' + url);
}
});
// Modelの定義
var UserSchema = new mongoose.Schema({
email : String,
password : String
},{collection: 'info'});
exports.User = db.model('User', UserSchema);
##controller
###routes/index.js
var model = require('../model.js')
で↑で定義したmodelの情報を読み込みます.
User = model.User;
とすることで↑のUserSchemaがroutes/index.js
でも使えるようになります.
また,sessionの情報はreq.session
に入っているのでconsole.log()などで確認してみるとわかると思います.
/*モデル読み込み*/
var model = require('../model.js'),
User = model.User;
/*ログイン後ページ*/
exports.index = function(req, res){
res.render('index', { user: req.session.user});
console.log(req.session.user);
};
/*ユーザー登録機能*/
exports.add = function(req, res){
var newUser = new User(req.body);
newUser.save(function(err){
if(err){
console.log(err);
res.redirect('back');
}else{
res.redirect('/');
}
});
};
/*ログイン機能*/
exports.login = function(req, res){
var email = req.query.email;
var password = req.query.password;
var query = { "email": email, "password": password };
User.find(query, function(err, data){
if(err){
console.log(err);
}
if(data == ""){
res.render('login');
}else{
req.session.user = email;
res.redirect('/');
}
});
};
##view
あとはフォームなどを作ればOKです.
###views/login.ejs
ログイン前のページです.
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ログイン前</title>
</head>
<body>
<h2>ログイン</h2>
<form action="/login" method="GET">
<input type="text" name="email" placeholder="Email"/>
<input type="password" name="password" placeholder="Password"/>
<input type="submit">ログイン</button>
</form>
<h2>新規登録</h2>
<form action="/add" method="POST">
<input type="text" name="email" placeholder="Email"/>
<input type="password" name="password" placeholder="Password"/>
<input type="submit">新規登録</button>
</form>
</body>
</html>
###views/index.ejs
ログイン後のページです.
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ログイン後</title>
</head>
<body>
<h1>My Site</h1>
<p>Welcome to My Site</p>
<%= user %> さんようこそ。
<p>
<a href="/logout">ログアウト</a>
</p>
</body>
</html>
##動作確認
ログイン前に/
or /index
にアクセスしようとするとリダイレクトで/login
が表示されると思います.新規登録(特に何も表示されませんが)をしてから新規登録したメールアドレスとパスワードでログインをすると/
を見れるはずです.また,ログアウトのリンクを押すとsessionが破棄され/logoin
に戻ると思います.
お疲れ様でした〜.