読者です 読者をやめる 読者になる 読者になる

node + express4 の router が実行される前に処理をハンドリングする

expressで認証周りを実装していて、
ログイン状態を判断するロジックを全てのrouterに実行させたい。
他のフレームワークだと、before() とか親クラスを用意して、
controllerが実行される前にチェックできるんだけど、
expressではどうするのか?

答えは簡単で、ミドルウェアを利用する。
ミドルウェアが分からない人はググッて下さい。

app.jsで以下の様なルーティング設定をしていると思うけど

import index = require('./routes/index');
app.use('/', index);

import user = require('./routes/user');
app.use('/user', user);

import study = require('./routes/study');
app.use('/study', study);

import mypage = require('./routes/mypage');
app.use('/mypage', mypage);

app.use(function(req, res, next) {
  let err = new Error('Not Found');
  err['status'] = 404;
  next(err);
});


これの最初に認証用ミドルウェアを設定してあげる。

//これが認証用のミドルウェア。
app.use( (req, res, next) => {
	if(req.isAuthenticated() === true){
		//ログイン済みなのでOK
		next();
	}else{
		switch(req.url){
			case '/':
			case '/user/signup':
			case '/user/signin':
				//ログイン不要なactionなのでOK
				AppLog.debug('not need auth');
				next();
				break;
			default:
				//ログイン必須なactionなのでNG
				next(AppException.createError(AppErrorRegistry.EXPIRED_SESSION));
		}
	}
});

import index = require('./routes/index');
app.use('/', index);

import user = require('./routes/user');
app.use('/user', user);

import study = require('./routes/study');
app.use('/study', study);

import mypage = require('./routes/mypage');
app.use('/mypage', mypage);

app.use(function(req, res, next) {
  let err = new Error('Not Found');
  err['status'] = 404;
  next(err);
});

こうすることで、各ルーティングが処理されるまでにチェックが可能になる。
ミドルウェアは app.use() した順番に処理がハンドリングされるので、
最後に app.use() しても実行されない。