Node.js + express で express-session でセッション管理する方法について、Express 4.x で、ログイン失敗時に、フラッシュ・メッセージを表示する方法についても備忘録です。
実現したい事は、ログインに失敗した場合、1回のリクエストのライフサイクルの間だけ、エラーメッセージ を表示する事です。
コードの修正箇所
以下のExpress4.x アプリケーション・ジェネレータの出力に、セッション管理とフラッシュメッセージを追加についての記録です。
$ express --css stylus myapp1
app.js のコードに、以下のコードを追加します。
<中略>
var favicon = require('serve-favicon');
var logger = require('morgan');
//セッション管理、ログイン失敗メッセージに必要なコード 追加部分ここから
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var flash = require('express-flash');
var handlebars = require('express-handlebars');
var sessionStore = new session.MemoryStore;
// 追加部分 ここまで
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
<中略>
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// セッション情報設定 追加部分ここから
app.use(cookieParser('secret'));
app.use(session({
cookie: { maxAge: 60000 },
store: sessionStore,
saveUninitialized: true,
resave: 'true',
secret: 'secret'
}));
app.use(flash());
// 追加部分 ここまで
// CSS プリプロセッサ設定
app.use(require('stylus').middleware(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
<中略>
// 追加部分 ここから
app.use(require('./login')); // ログイン ミドルウェア
app.use('/', routes); // ログイン画面、トップ画面送出
app.use('/logout', routes); // ログアウト処理 POSTで対応
app.use('/users', users); // コンテンツ表示
// 追加部分 ここまで、
// catch 404 and forward to error handler
// ログインしてない場合は、login.js で捕捉して、ログインページへ飛ばす
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// 以下1行追加
app.use('/:page', routes); // デフォルト設定 ルート以下全て、routesへルーティング
login.js の ログイン管理のミドルウェアに変更を加えます。 ログインに失敗した時に、ログインフォームに表示するフラッシュメッセージをセットします。 var login から始まる行に、判定条件 && req.url != '/logout' を追加します。
File Edit Options Buffers Tools Javascript Help
var users = { 'tkr': 'password' }; // ユーザーパスワード
module.exports = function(req, res, next) {
var method = req.method.toLowerCase();
var user = req.body;
var logout = (method === 'post' && req.url === '/logout');
var login = (method === 'post' && user && req.url != '/logout'); // 条件変更
// ログアウト
if (logout) {
delete req.session.user;
}
// ログイン
if (login) {
Object.keys(users).forEach(function(name) {
if (user.name === name && user.pwd === users[name]) {
req.session.user = {
name: user.name,
pwd: user.pwd
};
// 追加部分 ここから
} else {
req.flash('success', 'ログイン失敗、ユーザー名またはパスワードが誤りです。');
}
// 追加部分 ここまで
});
}
// セッションが無ければ ログイン画面へ
if (!req.session.user) {req.url = '/'}
next();
}
ルーター設定ファイルの res.render から始まる行で、JSONの要素 expressFlash: req.flash('success') を追加します。 これで画面VIEWファイルに、フラッシュ・メッセージが伝達され表示可能となります。
var express = require('express');
var router = express.Router();
function render(req, res, next) {
res.render('index', { title: 'Express', user: req.session.user, expressFlash: req.flash('success') });
}
router.get('/', function(req, res, next) {
render(req, res, next);
});
router.post('/', function(req, res, next) {
render(req, res, next);
});
module.exports = router;
JADEのファイルの最後の部分に、2行追加します。 これで、#{ expressFlash } の部分がメッセージに置き換わります。
<中略>
p
label(for='pwd') パスワード:
input(type='password', name='pwd')
input(type='submit')
// 以下2行を追加
if expressFlash.length > 0
p <strong>エラーメッセージ:</strong> #{ expressFlash }
パッケージ追加
以下、Express コマンドで作成される package.json に加えて 3つのモジュールをインストールします。
$ npm install express-session --save
$ npm install express-flash --save
$ npm install express-handlebars --save
生成された package.json は、以下の様になります。
$ cat package.json
{
"name": "myapp1",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "~1.15.1",
"cookie-parser": "~1.4.3",
"debug": "~2.2.0",
"express": "~4.13.4",
"express-flash": "0.0.2",
"express-handlebars": "^3.0.0",
"express-session": "^1.15.2",
"jade": "~1.11.0",
"morgan": "~1.7.0",
"serve-favicon": "~2.3.0",
"stylus": "0.54.5"
}
}
アプリ実行
以下のコマンドを実行して、アプリをスタートします。
$ pwd
myapp1
$ npm start
以上です。
参考資料
[1] npm express-flash https://www.npmjs.com/package/express-flash