6
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Express4 で フラッシュメッセージを利用する方法のメモ

Last updated at Posted at 2017-05-15

Node.js + express で express-session でセッション管理する方法について、Express 4.x で、ログイン失敗時に、フラッシュ・メッセージを表示する方法についても備忘録です。

実現したい事は、ログインに失敗した場合、1回のリクエストのライフサイクルの間だけ、エラーメッセージ を表示する事です。
スクリーンショット 2017-05-15 21.49.44.png

コードの修正箇所

以下のExpress4.x アプリケーション・ジェネレータの出力に、セッション管理とフラッシュメッセージを追加についての記録です。

$ express --css stylus myapp1

app.js のコードに、以下のコードを追加します。

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' を追加します。

myapp1/login.js
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ファイルに、フラッシュ・メッセージが伝達され表示可能となります。

myapp1/routes/index.js
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 } の部分がメッセージに置き換わります。

myapp1/views/login.jade部分
<中略>
       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 は、以下の様になります。

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

6
14
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?