Express express-validatorでバリデーションチェックする

こんにちは。レモンティーです。

今回は、express-validatorでバリデーションチェックをします。
express-validator.github.io

準備

まずはnpmでインストールします。

npm install --save express-validator

あとは使いたいファイルで

var { check,validationResult } = require("express-validator/check");

で使用できます。

使ってみる

以下のようにcheckメソッドにチェックしたいパラメータの名前を渡して、そこにvalidator.jsのメソッドをチェーンしていけばOKです。結果はvalidationResultに入っています。

router.post("/",[
  check("email").isEmail()
],(req,res) => {
  const errors = validationResult(req);
  if(!errors.isEmpty()){
    //errorアリの時
  }
});

errorsは配列になっていて、それぞれのcheckの結果のオブジェクトが格納されています。

また、checkメソッドではbodyだけでなくcookieやqueryやparamsもチェックしますので、例えば「bodyのみ」など特定の部分だけでいいときは以下のようにも書けます。

var { body,validationResult } = require("express-validator/check");

router.post("/",[
  body("email").isEmail()
],(req,res) => {
  const errors = validationResult(req);
  if(!errors.isEmpty()){
    //errorアリの時
  }
});

さらに、チェーンには以下のようにサニタイズ用のメソッドも一緒につなげることができます。

check("email")
  .isEmail()
  .normalizeEmail()

Custom Validator

customメソッドを使うことで独自のバリデーションメソッドを作成できます。

.custom((value,{req,location,path}) => {
  if(value !== req.body.password){
    return Promise.reject("error message")
  }
  return Promise.resolve(value);
})

エラーメッセージ

デフォルトのエラーメッセージは全部「Invalid Value」ですが、withMessageメソッドを使うことで変更できます。

check("abc")
  .isEmail().withMessage("Invalid Email")

まとめ

ここまでの内容をまとめたサンプルです。

index.js

var express = require('express');
var router = express.Router();
var models = require("../models");
var { check,validationResult } = require("express-validator/check");

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { messages: [] });
});

router.post('/',[
  check("email")
    .isEmail()
    .custom(value => {
      return models.User.findOne({email:value}).then(user => {
        if(user){
          return Promise.reject("このメールアドレスはすでに使用されています")
        }
        return Promise.resolve(value);
      })
    }),
  check("password")
    .isAlphanumeric().withMessage("パスワードには半角英数のみ使用できます。")
    .isLength({min:6,max:8}).withMessage("パスワードは6~8文字です"),
  check("passwordComfirmation")
    .custom((value,{req}) => {
      if(value !== req.body.password){
        return Promise.reject("パスワードが一致していません");
      }
      return Promise.resolve(value);
    })
],(req, res, next) => {
  const errors = validationResult(req);
  if(!errors.isEmpty()){
    res.render("index",{messages:errors.array()});
  }else{
    res.render("index",{messages:[{param:"",msg:"OK"}] });
  }
});

module.exports = router;

index.ejs

<!DOCTYPE html>
<html>
  <head>
    <title>Sample</title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1>Sample</h1>

    <h2>Message</h2>
    <% for(var message of messages) {%>
      <p><%= message.param %> : <%= message.msg %></p>
    <% } %>

    <h2>Form</h2>
    <form action="/" method="POST">
      <input type="email" name="email" placeholder="メールアドレス">
      <input type="password" name="password" placeholder="パスワード(半角英数6~8文字)">
      <input type="password" name="passwordComfirmation" placeholder="パスワード確認">
      <input type="submit" value="OK">
    </form>
  </body>
</html>


今回はこれでおしまいです。