Jonathan Wexler/吉川 邦夫 翔泳社 2019年09月25日頃
Lesson22
フラッシュメッセージを表示する
- connect-flashパッケージを使う。
- セッションとクッキーが使われるのでcookie-parser express-sessionも必要となる。
- npm install express ejs express-ejs-layouts http-status-codes connect-flash cookie-parser express-session mongo mongoose
'use strict';
const express = require('express');
const expressSession = require("express-session");
const cookieParser = require("cookie-parser");
const connectFlash = require("connect-flash");
const app = express();
app.set('port', process.env.PORT || 3000);
app.set("view engine", "ejs");
app.use(cookieParser("secret_passcode"));
app.use(
expressSession({
secret: "secret_passcode",
cookie: {
maxAge: 4000000
},
resave: false,
saveUninitialized: false
})
);
app.use(connectFlash());
// フラッシュメッセージをviewから参照できるようにするためのミドルウェア関数
app.use((req, res, next) => {
res.locals.flashMessages = req.flash();
next();
});
app.get('/hoge', (req, res, next) => {
req.flash('success', '成功しました。')
res.redirect('/');
next();
});
app.get('/', (req, res) => {
res.render('index');
});
app.listen(app.get('port'), () => {
console.log(`Server running at http://localhost:${app.get('port')}`);
});
<% if (flashMessages && flashMessages.success) { %>
<p><%= flashMessages.success %></p>
<% } %>
Lesson23
パスワードにハッシュをかける
- ここではbcryptでハッシュ化しているが、passportを使うのが一般的。
- npm install bcrypt
以下のように利用。
const bcrypt = require("bcrypt");
const salt = bcrypt.genSaltSync(10);
const hash = bcrypt.hashSync(req.body.password, salt);
※ Userモデルのpre(‘save’)フックでハッシュ化するとよい。
- compareSyncメソッドで比較可能。
bcrypt.compareSync(req.body.password, bcrypt.hashSync('hogehoge', salt))
※compareSyncメソッドはソルトの情報を抜き出し、指定回数ハッシュ化して比較している。
非同期のhashメソッドやcompareメソッドがあり、ハッシュ化はある程度時間がかかるためサーバーアプリケーションではこちらを使うべき。
バリデーションを追加する
- モデルのスキーマ定義でバリデーションが行われているが、express-validatorパッケージを使うことでモデルに到達する前にミドルウェア関数でバリデーションを行うことできる。
npm install express-validator
※ バージョン6から使い方が変わったので注意
router.post("/users/create", usersController.validate, usersController.create, usersController.redirectView);
のように経路の先頭にバリデーション用のミドルウェア関数として追加するとよい。
const { body, validationResult } = require('express-validator');
// 利用方法サンプル
app.post('/validate',
body("message").trim().isLength({min:5, max: 10}),
body("email").trim().isEmail(),
(req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
let errMessages = [];
for (const error of errors.array()) {
errMessages.push(error.msg);
}
req.flash('success', errMessages.join(','));
res.redirect('/');
}
next();
}
);
Lesson24
Passport.jsを使う
- Passport.jsは最も利用されている認証用ミドルウェアである。
- 認証方法(ストラテジー)はOAuthやFacebook認証などにも対応しているが、通常はローカル認証を使う。
- npm install passport passport-local-mongoose
passport = require("passport");
User = require("./models/user");
router.use(passport.initialize());
router.use(passport.session()); // Expressのセッションを使う
passport.use(User.createStrategy()); // ストラテジーを設定
passport.serializeUser(User.serializeUser()); // Userモデルでシリアライズを行う
passport.deserializeUser(User.deserializeUser());
const passportLocalMongoose = require("passport-local-mongoose");
userSchema.plugin(passportLocalMongoose, {
usernameField: "email"
}); // この行を追加するとPassportがパスワード用のフィールドを追加してくれるので、スキーマ定義からpasswordは削除する
// 登録処理
const newUser = {
name: req.body.name,
email: req.body.email,
};
User.register(newUser, req.body.password, (err, user) => {
if (user) {
console.log(user);
}
});
// ログイン処理
// ミドルウェア関数にpassport.authenticate()を指定する。
app.post('/login', passport.authenticate("local", {
failureRedirect: "/login",
failureFlash: "ログイン失敗",
successRedirect: "/",
}));
// ※successFlashはなくなったっぽい
// ※ログインしているかはreq.isAuthenticated()、ログインユーザーはreq.userで取得可能
// ログアウト処理
app.post('/logout', (req, res) => {
req.logout(()=>{
req.flash('success', 'ログアウトしました。')
res.redirect('/');
});
});
// Passportのバージョン0.6から非同期処理になったので注意
コメント