ファイルの編集
以下のパッケージをインストールします。
// connect-flash
npm install connect-flash
// express-session
npm install express-session
Express-generator で作成されたアプリのファイルを以下のように編集します。
app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const session = require('express-session'); // 追加
const flash = require('connect-flash'); // 追加
const crypto = require("crypto"); // 追加
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// 追加
function generateCsrfToken(){
return crypto.randomBytes(32).toString('hex');
}
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// 追加
app.use(session({
secret: 'secret_key',
resave: false,
saveUninitialized: false
}));
// 追加
app.use((req, res, next) => {
if (!req.session.csrfToken) {
req.session.csrfToken = generateCsrfToken();
}
next();
});
app.use(flash()); // 追加
... 省略 ...
routes/index.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
const csrfToken = req.session.csrfToken;
res.render('index', { msg: "", csrfToken: csrfToken });
});
router.post('/', function(req, res, next) {
const receivedToken = req.body.csrfToken;
// エラー処理を確認する場合、トークンを一致しないように上記をコメントアウトし、以下のコメントアウトを解除します
// const receivedToken = "エラー";
const sessionToken = req.session.csrfToken;
console.log(receivedToken);
console.log(sessionToken);
if (receivedToken === sessionToken){
console.log('フォームが正常に送信されました!');
const csrfToken = req.session.csrfToken;
return res.render("index", { msg: 'トークンは一致しました', csrfToken: csrfToken });
} else {
console.log('フォームの送信に失敗しました。');
req.flash( 'msg', 'トークンが一致しません' );
return res.redirect("/");
}
});
module.exports = router;
views/index.ejs
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1>formの送信</h1>
<p>
<% if(msg != '') { %>
<%= msg %>
<% } %>
</p>
<form action="/" method="POST">
<input type="hidden" name="csrfToken" value="<%= csrfToken %>">
<input type="text">
<input type="submit"></button>
</form>
</body>
</html>