express-validatorは、expressのミドルウェアとしてリクエストデータをバリデーションする機能を提供してます。内部では、validator.js を利用してます。ここでは、express-validatorの利用方法について確認します。
目次
express-validatorをインストール
$ npm install --save express-validator
(省略)
$ npm list|grep express-validator
└─┬ express-validator@5.1.2
リクエストデータの検証|validation
( checkモジュールで検証 )
実装例
checkモジュール
で検証ルールを設定して、validationResultモジュール
で検証結果を確認します。
const express = require('express')
const bodyParser = require('body-parser')
const { check, validationResult } = require('express-validator/check')
const app = express()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.post(
'/users',
// バリデーションルール
[
check('name').isLength({ min: 5, max: 10}).isAlphanumeric().exists(),
check('mail').isEmail(),
check('password').isLength({ min: 5 }),
check('weekday').not().isIn(['sunday', 'saturday'])
],
(req, res) => {
// 検証
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() })
}
res.status(200).end()
}
)
app.listen(5000, () => console.log('Example app listening on port 5000!'))
動作確認
まずは、検証NGの例を確認します。
$ http -v POST localhost:5000/users name=1234 mail=aaa password=1234 weekday=sunday
POST /users HTTP/1.1
Accept: application/json, */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 72
Content-Type: application/json
Host: localhost:5000
User-Agent: HTTPie/1.0.2
{
"mail": "aaa",
"name": "1234",
"password": "1234",
"weekday": "sunday"
}
HTTP/1.1 422 Unprocessable Entity
Connection: keep-alive
Content-Length: 308
Content-Type: application/json; charset=utf-8
Date: Sun, 21 Oct 2018 08:51:02 GMT
ETag: W/"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
X-Powered-By: Express
{
"errors": [
{
"location": "body",
"msg": "Invalid value",
"param": "name",
"value": "1234"
},
{
"location": "body",
"msg": "Invalid value",
"param": "mail",
"value": "aaa"
},
{
"location": "body",
"msg": "Invalid value",
"param": "password",
"value": "1234"
},
{
"location": "body",
"msg": "Invalid value",
"param": "weekday",
"value": "sunday"
}
]
}
次に検証OKの例を確認します。
$ http POST localhost:5000/users name=12345 mail=aaa@bbb.com password=12345 weekday=monday
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 0
Date: Sun, 21 Oct 2018 08:15:14 GMT
X-Powered-By: Express
検証対象の調整
リクエストデータの検証対象は下記メソッドで調整できます。
method | 検証対象 |
---|---|
check([field, message]) | req.body req.cookies req.headers req.params req.query |
body([fields, message]) | req.body |
cookie([fields, message]) | req.cookies |
header([fields, message]) | req.headers |
param([fields, message]) | req.params |
query([fields, message]) | req.query |
参考
リクエストデータの検証|validation
( checkSchemaモジュールで検証 )
実装例
checkSchemaモジュール
で検証ルールを設定して、validationResultモジュール
で検証結果を確認します。
const express = require('express')
const bodyParser = require('body-parser')
const { checkSchema, validationResult } = require('express-validator/check')
const app = express()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.post(
'/users',
// バリデーションルール
checkSchema({
name: {
in: ['body'],
isLength: {
options: { min: 5, max: 10 }
},
isAlphanumeric: true,
exists: true
},
mail: {
in: ['body'],
isEmail: true
},
password: {
in: ['body'],
isLength: { options: { min: 5 } }
},
weekday: {
in: ['body'],
isIn: {
options: ['sunday', 'saturday'],
negated: true
}
}
}),
(req, res) => {
// 検証
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() })
}
res.status(200).end()
}
)
app.listen(5000, () => console.log('Example app listening on port 5000!'))
動作確認
まずは、検証NGの例を確認します。
$ http -v POST localhost:5000/users name=1234 mail=aaa password=1234 weekday=sunday
POST /users HTTP/1.1
Accept: application/json, */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 72
Content-Type: application/json
Host: localhost:5000
User-Agent: HTTPie/1.0.2
{
"mail": "aaa",
"name": "1234",
"password": "1234",
"weekday": "sunday"
}
HTTP/1.1 422 Unprocessable Entity
Connection: keep-alive
Content-Length: 308
Content-Type: application/json; charset=utf-8
Date: Sun, 21 Oct 2018 08:48:21 GMT
ETag: W/"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
X-Powered-By: Express
{
"errors": [
{
"location": "body",
"msg": "Invalid value",
"param": "name",
"value": "1234"
},
{
"location": "body",
"msg": "Invalid value",
"param": "mail",
"value": "aaa"
},
{
"location": "body",
"msg": "Invalid value",
"param": "password",
"value": "1234"
},
{
"location": "body",
"msg": "Invalid value",
"param": "weekday",
"value": "sunday"
}
]
}
次に検証OKの例を確認します。
$ http POST localhost:5000/users name=12345 mail=aaa@bbb.com password=12345 weekday=monday
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 0
Date: Sun, 21 Oct 2018 08:49:57 GMT
X-Powered-By: Express
参考
リクエストデータの無害化|sanitization
実装例
trim
を利用すると、前後の余計な空白を削除してくれます。
const express = require('express')
const bodyParser = require('body-parser')
const { check, validationResult } = require('express-validator/check')
const app = express()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.post(
'/users',
// バリデーションルール
[
check('mail1').isEmail(),
check('mail2').isEmail().trim(),
check('mail3').trim().isEmail(),
],
(req, res) => {
// 検証
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() })
}
res.send({
mail1: req.body.mail1,
mail2: req.body.mail2,
mail3: req.body.mail3
})
}
)
app.listen(5000, () => console.log('Example app listening on port 5000!'))
動作確認
下記例では、mailがバリデーションエラーとなります。mail1
は、検証ルールにて trimメソッド
を組み込んでないためです。
$ http -v POST localhost:5000/users 'mail1= aaa@bbb.com ' 'mail2= aaa@bbb.com ' 'mail3= aaa@bbb.com '
POST /users HTTP/1.1
Accept: application/json, */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 78
Content-Type: application/json
Host: localhost:5000
User-Agent: HTTPie/1.0.2
{
"mail1": " aaa@bbb.com ",
"mail2": " aaa@bbb.com ",
"mail3": " aaa@bbb.com "
}
HTTP/1.1 422 Unprocessable Entity
Connection: keep-alive
Content-Length: 94
Content-Type: application/json; charset=utf-8
Date: Sun, 21 Oct 2018 09:10:58 GMT
ETag: W/"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
X-Powered-By: Express
{
"errors": [
{
"location": "body",
"msg": "Invalid value",
"param": "mail1",
"value": " aaa@bbb.com "
}
]
}
mail1
のみ前後の空白を削除してリクエストします。mail2
mail3
は trimメソッド
によって前後の空白が削除されていることを確認できます。
$ http -v POST localhost:5000/users 'mail1=aaa@bbb.com' 'mail2= aaa@bbb.com ' 'mail3= aaa@bbb.com '
POST /users HTTP/1.1
Accept: application/json, */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 76
Content-Type: application/json
Host: localhost:5000
User-Agent: HTTPie/1.0.2
{
"mail1": "aaa@bbb.com",
"mail2": " aaa@bbb.com ",
"mail3": " aaa@bbb.com "
}
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 67
Content-Type: application/json; charset=utf-8
Date: Sun, 21 Oct 2018 09:14:58 GMT
ETag: W/"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
X-Powered-By: Express
{
"mail1": "aaa@bbb.com",
"mail2": "aaa@bbb.com",
"mail3": "aaa@bbb.com"
}
参考
- https://express-validator.github.io/docs/sanitization.html
- https://github.com/chriso/validator.js#sanitizers