セッションの機能を使って簡単な認証機能を実装できます。
必要なモジュールのインストール
セッションを使うので express-session
を、フォームからのリクエストを受けるのでリクエストボディをパースするために body-parser
をインストールします。
$ npm install --save express-session body-parser
実装の手順
まず、メインの処理を行う前にセッションをチェックし、セッションにユーザー名が入っていなければログインページにリダイレクトをするミドルウェアを定義します。
app.use((req, res, next) => {
if (req.session.username) {
next();
} else {
res.redirect('/login');
}
});
ログインページでは、ユーザー名とパスワードの入力を受け付けたらパスワードを照合し、正しければセッションを生成します。
(当然ですが、実際に運用する時はパスワードのハッシュ化やCSRF対策などを行なってください)
app.get('/login', (req, res) => {
res
.type('text/html')
.send(
`<form method="POST" action="/login">
<div>username<input type="text" name="username"></div>
<div>password<input type="password" name="password"></div>
<div><input type="submit" name="login"></div>
</form>`
)
});
app.post('/login', (req, res) => {
const username = req.body.username;
const password = req.body.password;
if (username === 'admin' && password === 'password') {
req.session.regenerate((err) => {
req.session.username = 'admin';
res.redirect('/');
});
} else {
res.redirect('/login');
}
});
ログアウトページではリクエストを受けたらセッションを破棄するメソッドを呼びます。
app.get('/logout', (req, res) => {
req.session.destroy((err) => {
res.redirect('/');
});
});
サンプルコードの全体
サンプルコードの全体は次のようになります。
ミドルウェアとルーティング定義の並び順には注意が必要です。
ログインのチェックを行うミドルウェアはログインページへのルーティング定義よりも後ろにおく必要があります。そうでないとログインページを参照するときもログインをチェックされるためにリダイレクトループが発生します。
const express = require('express');
const session = require('express-session');
const bodyParser = require('body-parser');
const app = express();
const sess = {
secret: 'secretsecretsecret',
cookie: { maxAge: 60000 },
resave: false,
saveUninitialized: false,
}
if (app.get('env') === 'production') {
app.set('trust proxy', 1)
sess.cookie.secure = true
}
app.use(session(sess))
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/login', (req, res) => {
res
.type('text/html')
.send(
`<form method="POST" action="/login">
<div>username<input type="text" name="username"></div>
<div>password<input type="password" name="password"></div>
<div><input type="submit" name="login"></div>
</form>`
)
});
app.post('/login', (req, res) => {
const username = req.body.username;
const password = req.body.password;
if (username === 'admin' && password === 'password') {
req.session.regenerate((err) => {
req.session.username = 'admin';
res.redirect('/');
});
} else {
res.redirect('/login');
}
});
app.get('/logout', (req, res) => {
req.session.destroy((err) => {
res.redirect('/');
});
});
app.use((req, res, next) => {
if (req.session.username) {
next();
} else {
res.redirect('/login');
}
});
app.get('/', (req, res) => {
res.send('Hello ' + req.session.username);
});
app.listen('3000', () => {
console.log('Application started');
});