gist

2012年4月22日日曜日

node-validatorを使ってみた

node-validatorは、入力値の検証(バリデーション)と無害化(サニタイズ)をしてくれるパッケージです。

$ npm install validator

node-validatorには、大きくcheckとsanitizeの機能があります。

check(検証)

check.coffee

check = require('validator').check

check('abc').isInt()

実行すると Invalid integer 例外が発生します。

$ coffee check.coffee 
Error: Invalid integer
    at [object Object].error (/Users/inouetomoyuki/node_modules/validator/lib/validator.js:7:11)
    at [object Object].isInt (/Users/inouetomoyuki/node_modules/validator/lib/validator.js:29:33)
    at Object.<anonymous> (/Users/inouetomoyuki/Projects/node/validator_sample/check.coffee:6:16)
    at Object.<anonymous> (/Users/inouetomoyuki/Projects/node/validator_sample/check.coffee:8:4)
    at Module._compile (module.js:441:26)
    at Object.run (/usr/local/lib/coffee-script/lib/coffee-script/coffee-script.js:73:25)
    at /usr/local/lib/coffee-script/lib/coffee-script/command.js:147:29
    at /usr/local/lib/coffee-script/lib/coffee-script/command.js:122:18
    at [object Object].<anonymous> (fs.js:115:5)
    at [object Object].emit (events.js:64:17)

try-catchで囲ってやります。

check.coffee

check = require('validator').check

try
    check('abc').isInt()
catch e
    console.log(e.message)
$ coffee check.coffee 
Invalid integer

エラーメッセージに変更するには、checkメソッドの第2引数に文字列を追加します。

check.coffee

check = require('validator').check

try
    check('abc', '整数を入力して下さい').isInt()
catch e
    console.log(e.message)
$ coffee check.coffee 
整数を入力して下さい

検証する内容をチェーンすることができます。

check.coffee

check = require('validator').check

try
    check('123', '4文字から12文字の整数を入力して下さい').len(4,12).isInt()
catch e
    console.log(e.message)
$ coffee check.coffee 
4文字から12文字の整数を入力して下さい

複数のエラーがあった場合、エラーの内容をまとめて取得したいことが多いです。Validatorクラスにちょっとだけメソッドを追加します。

check.coffee

Validator = require('validator').Validator

Validator.prototype.error = (msg) ->
    this._errors.push msg

Validator.prototype.getErrors = () ->
    return this._errors

validator = new Validator()

validator.check('hello', '10文字から30文字の文字列を入力して下さい').len(10,30)
validator.check('1234', '5桁以上の整数を入力してください').isInt().len(5,30)
validator.check('1234-5678', '正しいクレジットカード番号を入力して下さい').isCreditCard()
validator.check('test', '正しいメールアドレスを入力して下さい').isEmail()

errors = validator.getErrors()

console.log(errors)
$ coffee check.coffee 
[ '10文字から30文字の文字列を入力して下さい',
  '5桁以上の整数を入力してください',
  '正しいクレジットカード番号を入力して下さい',
  '正しいメールアドレスを入力して下さい' ]

クレジットカード番号は、Visa、MasterCard、American Express、Discover、Diners Club、JCBカードのフォーマットに対応しているとのことです。

checkでは、以下の検証ができます。

is()                //regex()のエイリアス
not()               //notRegex()のエイリアス
isEmail()           //メールアドレス
isUrl()         //http, https, ftpのURL
isIP()              //IPアドレス
isAlpha()           //英字
isAlphanumeric()    //英数字
isNumeric()     //数字
isInt()         //整数。0パディングはエラー。
isLowercase()       //小文字
isUppercase()       //大文字
isDecimal()     //数字
isFloat()           //isDecimal()のエイリアス
notNull()           //Nullでない
isNull()            //Null
notEmpty()          //空でないこと。ホワイトスペースだけもエラー。
equals(equals)  //等しい
contains(str)       //含む
notContains(str)    //含まない
regex(pattern, modifiers)   //正規表現にマッチ
notRegex(pattern, modifiers)    //正規表現にマッチしない
len(min, max)   //長さ
isUUID(version)     //UUIDかどうか
isDate()            //日付かどうか。Date.parseで通ること。regex使ったほうがいいかも?
isAfter(date)       //dateより未来であること
isBefore(date)  //dateより過去であること
isIn(options)       //optionsに含まれていること。arrayかstring
notIn(options)  //optionsに含まれていないこと
max(val)            //最大値
min(val)            //最小値
isArray()           //配列であること
isCreditCard()  //クレジットカード番号

sinitize(無害化とフィルター)

XSS攻撃対策として無害化/フィルターは必須の技術です。

sanitize.coffee

sanitize = require('validator').sanitize

int = sanitize('0123').toInt() console.log(int) bool = sanitize('true').toBoolean() console.log(bool) str = sanitize(' \s hello ').trim() console.log(str) str = sanitize('aaaaaaaaab').ltrim('a') console.log(str) str = sanitize('
b
').xss() console.log(str) str = sanitize('<a>').entityDecode() console.log(str)
$ coffee sanitize.coffee 
123
true
 hello
b
<div style="color:5xpression(alert&#40;'XSS2'&#41;);">b</div>
<a>

その他、無害化/フィルターには以下のようなものがあります。

trim(chars)   //ホワイトスペースや改行、タブなどのトリム。指定した文字によるトリム。
ltrim(chars)  //指定した文字で左からトリム
rtrim(chars)  //指定した文字で右からトリム
ifNull(replace)  //nullだったら置き換える
toFloat()  //floatに
toInt()    //intに
toBoolean() //booleanに。文字列長がゼロ。'0', 'false'はfalseになる
toBooleanStrict() // '1','true'以外はfalse
entityDecode()   //HTMLにデコード
entityEncode()   //HTMLをエンコード
xss()  // テキストによるXSS攻撃の無効化
xss(true) //イメージによるXSS攻撃の無効化

0 件のコメント: