「入門Node.jsプログラミング 」の感想・備忘録8

「入門Node.jsプログラミング 」の感想・備忘録7の続き

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から非同期処理になったので注意

【新しい記事】

【古い記事】

コメントを残す

メールアドレスが公開されることはありません。