validation: Bibliothèque de validation (Validation et filtrage des entrées) pour Lua et nginx-module-lua
Installation
Si vous n'avez pas encore configuré l'abonnement au dépôt RPM, inscrivez-vous. Ensuite, vous pouvez procéder avec les étapes suivantes.
CentOS/RHEL 7 ou Amazon Linux 2
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install lua-resty-validation
CentOS/RHEL 8+, Fedora Linux, Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-validation
Pour utiliser cette bibliothèque Lua avec NGINX, assurez-vous que nginx-module-lua est installé.
Ce document décrit lua-resty-validation v2.7 publié le 25 août 2017.
lua-resty-validation est une bibliothèque de validation et de filtrage par chaînage extensible pour Lua et OpenResty.
Hello World avec lua-resty-validation
local validation = require "resty.validation"
local valid, e = validation.number:between(0, 9)(5) -- valid = true, e = 5
local valid, e = validation.number:between(0, 9)(50) -- valid = false, e = "between"
-- Les validateurs peuvent être réutilisés
local smallnumber = validation.number:between(0, 9)
local valid, e = smallnumber(5) -- valid = true, e = 5
local valid, e = smallnumber(50) -- valid = false, e = "between"
-- Les validateurs peuvent faire du filtrage (c'est-à-dire modifier la valeur validée)
-- valid = true, s = "HELLO WORLD!"
local valid, s = validation.string.upper "hello world!"
-- Vous pouvez étendre la bibliothèque de validation avec vos propres validateurs et filtres...
validation.validators.capitalize = function(value)
return true, value:gsub("^%l", string.upper)
end
-- ... et ensuite l'utiliser
local valid, e = validation.capitalize "abc" -- valid = true, e = "Abc"
-- Vous pouvez également valider plusieurs valeurs en groupe
local group = validation.new{
artist = validation.string:minlen(5),
number = validation.tonumber:equal(10)
}
local valid, fields, errors = group{ artist = "Eddie Vedder", number = "10" }
if valid then
print("tous les champs du groupe sont valides")
else
print(fields.artist.name, fields.artist.error,
fields.artist.valid, fields.artist.invalid,
fields.artist.input, fields.artist.value, ,
fields.artist.validated, fields.artist.unvalidated)
end
-- Vous pouvez même appeler fields pour obtenir un tableau simple de noms et de valeurs
-- (dans ce cas, tous les `nil` sont également supprimés)
-- Par défaut, cela ne retourne que les noms et valeurs des champs valides :
local data = fields()
local data = fields "valid"
-- Pour obtenir uniquement les noms et valeurs des champs invalides, appelez :
local data = fields "invalid"
-- Pour obtenir uniquement les noms et valeurs des champs validés, appelez (qu'ils soient valides ou non) :
local data = fields "validated"
-- Pour obtenir uniquement les noms et valeurs des champs non validés, appelez (qu'ils soient valides ou non) :
local data = fields "unvalidated"
-- Pour obtenir tout, appelez :
local data = fields "all"
-- Ou combinez :
local data = fields("valid", "invalid")
-- Cela ne s'arrête pas là. Vous pouvez également vouloir obtenir uniquement certains champs par leur nom.
-- Vous pouvez le faire en appelant (retourne un tableau) :
local data = data{ "artist" }
Validateurs et filtres intégrés
lua-resty-validation est livré avec plusieurs validateurs intégrés, et le projet est ouvert aux contributions de nouveaux validateurs.
Validateurs et filtres sans arguments
Les validateurs de type peuvent être utilisés pour valider le type de la valeur validée. Ces validateurs sont sans argument
(appelez-les avec un point .) :
nullou["nil"](car nil est un mot-clé réservé en Lua)booleannumberstringtableuserdatafuncou["function"](car function est un mot-clé réservé en Lua)callable(soit une fonction soit une table avec la métaméthode__call)threadintegerfloatfile(io.type(value) == 'file')
Filtres de conversion de type :
tostringtonumbertointegertoboolean
Autres filtres :
toniloutonullabsinfnanfinitepositivenegativeloweruppertrimltrimrtrimreverseemailoptional
Exemple
local validation = require "resty.validation"
local ok, e = validation.null(nil)
local ok, e = validation.boolean(true)
local ok, e = validation.number(5.2)
local ok, e = validation.string('Hello, World!')
local ok, e = validation.integer(10)
local ok, e = validation.float(math.pi)
local f = assert(io.open('filename.txt', "r"))
local ok, e = validation.file(f)
Validateurs et filtres de la fabrique de validation
La fabrique de validation se compose de différents validateurs et filtres utilisés pour valider ou filtrer la valeur
(appelez-les avec deux-points :) :
type(t), valide que la valeur est de typet(voir les validateurs de type)nil()ou["null"](), vérifie que le type de valeur estnilboolean(), vérifie que le type de valeur estbooleannumber(), vérifie que le type de valeur estnumberstring(), vérifie que le type de valeur eststringtable(), vérifie que le type de valeur esttableuserdata(), vérifie que le type de valeur estuserdatafunc()ou["function"](), vérifie que le type de valeur estfunctioncallable(), vérifie que la valeur est callable (c'est-à-dire une fonction ou une table avec la métaméthode__call)thread(), vérifie que le type de valeur estthreadinteger(), vérifie que le type de valeur estintegerfloat(), vérifie que le type de valeur estfloatfile(), vérifie que le type de valeur estfile(io.type(value) == 'file')abs(), filtre la valeur et retourne la valeur absolue (math.abs)inf(), vérifie que la valeur estinfou-infnan(), vérifie que la valeur estnanfinite(), vérifie que la valeur n'est pasnan,infou-infpositive(), valide que la valeur est positive (> 0)negative(), valide que la valeur est négative (< 0)min(min), valide que la valeur est au moinsmin(>=)max(max), valide que la valeur est au plusmax(<=)between(min[, max = min]), valide que la valeur est entreminetmaxoutside(min[, max = min]), valide que la valeur n'est pas entreminetmaxdivisible(number), valide que la valeur est divisible parnumberindivisible(number), valide que la valeur n'est pas divisible parnumberlen(min[, max = min]), valide que la longueur de la valeur est exactementminou entreminetmax(UTF-8)minlen(min), valide que la longueur de la valeur est au moinsmin(UTF-8)maxlen(max), valide que la longueur de la valeur est au plusmax(UTF-8)equals(equal)ouequal(equal), valide que la valeur est exactement quelque choseunequals(equal)ouunequal(equal), valide que la valeur n'est pas exactement quelque choseoneof(...), valide que la valeur est égale à l'un des arguments fournisnoneof(...), valide que la valeur n'est pas égale à aucun des arguments fournismatch(pattern[, init]), valide que la valeur correspond (string.match) au motifunmatch(pattern[, init]), valide que la valeur ne correspond pas (string.match) au motiftostring(), convertit la valeur en chaînetonumber([base]), convertit la valeur en nombretointeger(), convertit la valeur en entiertoboolean(), convertit la valeur en booléen (en utilisantnot not value)tonil()outonull(), convertit la valeur en nillower(), convertit la valeur en minuscules (le support UTF-8 n'est pas encore implémenté)upper(), convertit la valeur en majuscules (le support UTF-8 n'est pas encore implémenté)trim([pattern]), supprime les espaces (vous pouvez également utiliser un motif) à gauche et à droiteltrim([pattern]), supprime les espaces (vous pouvez également utiliser un motif) à gauchertrim([pattern]), supprime les espaces (vous pouvez également utiliser un motif) à droitestarts(starts), vérifie si la chaîne commence parstartsends(ends), vérifie si la chaîne se termine parendsreverse, inverse la valeur (chaîne ou nombre) (UTF-8)coalesce(...), si la valeur est nil, retourne la première valeur non-nil passée en argumentsemail(), valide que la valeur est une adresse emailcall(function), valide / filtre la valeur contre un validateur / filtre personnalisé en ligneoptional([default]), arrête la validation si la valeur est une chaîne vide""ounilet retournetrue, et soit,defaultouvalue
Validateurs de fabrique de validation conditionnels
Pour tous les validateurs de fabrique de validation, il existe une version conditionnelle qui valide toujours à vrai, mais où vous pouvez remplacer la valeur réelle en fonction de la validation du validateur d'origine. Eh bien, c'est plus facile à montrer qu'à dire :
local validation = require "resty.validation"
-- ok == true, value == "Oui, la valeur est nil"
local ok, value = validation:ifnil(
"Oui, la valeur est nil",
"Non, vous n'avez pas fourni de valeur nil")(nil)
-- ok == true, value == "Non, vous n'avez pas fourni de valeur nil"
local ok, value = validation:ifnil(
"Oui, la valeur est nil",
"Non, vous n'avez pas fourni de valeur nil")("non nil")
-- ok == true, value == "Oui, le nombre est entre 1 et 10"
local ok, value = validation:ifbetween(1, 10,
"Oui, le nombre est entre 1 et 10",
"Non, le nombre n'est pas entre 1 et 10")(5)
-- ok == true, value == "Non, le nombre n'est pas entre 1 et 10"
local ok, value = validation:ifbetween(1, 10,
"Oui, le nombre est entre 1 et 10",
"Non, le nombre n'est pas entre 1 et 10")(100)
Les deux derniers arguments des validateurs de fabrique de validation conditionnels sont les valeurs truthy et falsy.
Chaque autre argument est passé au validateur de fabrique de validation réel.
Validateurs de groupe
lua-resty-validation prend actuellement en charge quelques validateurs prédéfinis :
compare(comparison), compare deux champs et définit les champs comme invalides ou valides selon la comparaisonrequisite{ fields }, au moins un des champs requis est nécessaire, même s'ils sont eux-mêmes optionnelsrequisites({ fields }, number), au moinsnumberde champs requis sont nécessaires (par défaut tous)call(function), appelle une fonction de validation de groupe personnalisée (ou en ligne)
local ispassword = validation.trim:minlen(8)
local group = validation.new{
password1 = ispassword,
password2 = ispassword
}
group:compare "password1 == password2"
local valid, fields, errors = group{ password1 = "qwerty123", password2 = "qwerty123" }
local optional = validation:optional"".trim
local group = validation.new{
text = optional,
html = optional
}
group:requisite{ "text", "html" }
local valid, fields, errors = group{ text = "", html = "" }
local optional = validation:optional ""
local group = validation.new{
text = optional,
html = optional
}
group:requisites({ "text", "html" }, 2)
-- ou group:requisites{ "text", "html" }
local valid, fields, errors = group{ text = "", html = "" }
group:call(function(fields)
if fields.text.value == "hello" then
fields.text:reject "le texte ne peut pas être 'hello'"
fields.html:reject "parce que le texte était 'hello', ce champ est également invalidé"
end
end)
Vous pouvez utiliser les opérateurs relationnels Lua normaux dans le validateur de groupe compare :
<><=>===~=
requisite et requisites vérifient si la valeur du champ est nil ou "" (chaîne vide).
Avec requisite, si tous les champs spécifiés sont nil ou "", alors tous les champs sont
invalides (à condition qu'ils ne soient pas eux-mêmes invalides), et si au moins un des champs
est valide, alors tous les champs sont valides. requisites fonctionne de la même manière, mais vous pouvez
définir le nombre de champs que vous souhaitez avoir une valeur qui n'est pas nil et pas
une chaîne vide "". Cela fournit une validation conditionnelle dans le sens de :
- J'ai (deux ou plusieurs) champs
- Tous sont optionnels
- Au moins un / un nombre défini de champs doit être rempli mais je me fiche de lequel tant qu'il y a au moins un / un nombre défini de champs remplis
Validateurs d'arrêt
Les validateurs d'arrêt, comme optional, sont comme des validateurs normaux, mais au lieu de retourner
true ou false comme résultat de validation OU comme valeur filtrée, vous pouvez retourner validation.stop.
Cette valeur peut également être utilisée à l'intérieur de validateurs conditionnels et dans des validateurs qui prennent en charge les valeurs par défaut. Voici comment
le validateur optional est implémenté :
function factory.optional(default)
return function(value)
if value == nil or value == "" then
return validation.stop, default ~= nil and default or value
end
return true, value
end
end
Ceux-ci sont à peu près équivalents :
-- Les deux retournent : true, "default" (ils arrêtent le traitement :minlen(10) sur les entrées nil et "")
local input = ""
local ok, val = validation.optional:minlen(10)(input)
local ok, val = validation:optional(input):minlen(10)(input)
local ok, val = validation:ifoneof("", nil, validation.stop(input), input):minlen(10)(input)
Filtrage de valeur et définition de la valeur à nil
La plupart des validateurs, qui ne filtrent pas la valeur, ne retournent que true ou false comme résultat.
Cela signifie qu'il n'y a maintenant aucun moyen de signaler à resty.validation de définir réellement la valeur à nil.
Donc, il y a une solution de contournement, vous pouvez retourner validation.nothing comme valeur, et cela changera la
valeur en nil, par exemple, le validateur intégré tonil est en fait implémenté comme ceci (pseudo) :
function()
return true, validation.nothing
end
Validateurs et filtres personnalisés (en ligne)
Parfois, vous pouvez simplement avoir des validateurs / filtres uniques que vous n'utilisez pas ailleurs, ou que vous voulez juste
fournir rapidement un validateur / filtre supplémentaire pour un cas spécifique. Pour faciliter cela, nous avons introduit la méthode de fabrique call avec lua-resty-validation 2.4. Voici un exemple :
validation:call(function(value)
-- maintenant validez / filtrez la valeur, et retournez les résultats
-- ici nous retournons simplement false (c'est-à-dire que la validation échoue)
return false
end)("Vérifiez cette valeur"))
(bien sûr, cela n'a pas besoin d'être une fonction en ligne car en Lua, toutes les fonctions sont des citoyens de première classe et peuvent être passées comme paramètres)
Extensions de validateurs intégrés
Actuellement, lua-resty-validation prend en charge deux extensions ou plugins que vous pouvez activer :
resty.validation.ngxresty.validation.tzresty.validation.utf8
Ce sont des choses que vous pouvez consulter si vous souhaitez créer votre propre extension de validateur. Si vous le faites, et que vous pensez qu'elle pourrait être utile pour d'autres également, n'oubliez pas d'envoyer votre extension sous forme de pull-request pour inclusion dans ce projet, merci beaucoup, ;-).
Extension resty.validation.ngx
Comme son nom l'indique, cet ensemble d'extensions de validateurs nécessite OpenResty (ou le module Lua Nginx au moins). Pour utiliser cette extension, tout ce que vous devez faire est :
require "resty.validation.ngx"
Cela patchera les adaptateurs qu'il fournira dans resty.validation, et ceux-ci sont actuellement :
escapeuriunescapeuribase64encbase64deccrc32shortcrc32longcrc32md5
(il existe à la fois une version de fabrique et une version sans argument de ceux-ci)
Il y a également un match regex dans l'extension ngx qui utilise ngx.re.match, et md5 paramétré :
regex(regex[, options])md5([bin])
Exemple
require "resty.validation.ngx"
local validation = require "resty.validation"
local valid, value = validation.unescapeuri.crc32("https://github.com/")
local valid, value = validation:unescapeuri():crc32()("https://github.com/")
Extension resty.validation.tz
Cet ensemble de validateurs et de filtres est basé sur la formidable bibliothèque luatz
de @daurnimator, qui est une bibliothèque pour la manipulation du temps et de la date. Pour utiliser cette extension, tout ce que vous devez
faire est :
require "resty.validation.tz"
Cela patchera les adaptateurs qu'il fournira dans resty.validation, et ceux-ci sont actuellement :
totimetabletotimestamp
(il existe à la fois une version de fabrique et une version sans argument de ceux-ci)
Les filtres totimestamp et totimetable fonctionnent très bien avec les champs d'entrée de date et de datetime HTML5. Comme son nom
l'indique, totimetable retourne un timetable luatz et totimestamp retourne des secondes depuis l'époque unix (1970-01-01)
sous forme de nombre Lua.
Exemple
require "resty.validation.tz"
local validation = require "resty.validation"
local valid, ts = validation.totimestamp("1990-12-31T23:59:60Z")
local valid, ts = validation.totimestamp("1996-12-19")
Extension resty.validation.utf8
Cet ensemble de validateurs et de filtres est basé sur la formidable bibliothèque utf8rewind
de Quinten Lansu - une bibliothèque système écrite en C conçue pour étendre les fonctions de manipulation de chaînes par défaut
avec le support du texte encodé en UTF-8. Elle nécessite mon wrapper LuaJIT FFI lua-resty-utf8rewind
pour fonctionner. Lorsque les exigences mentionnées sont installées, le reste est facile. Pour utiliser cette extension, tout ce que vous devez
faire est :
require "resty.validation.utf8"
Cela patchera les adaptateurs qu'il fournira dans resty.validation, et ceux-ci sont actuellement :
utf8upperutf8lowerutf8title
(il existe à la fois une version de fabrique et une version sans argument de ceux-ci)
Il y a également quelques validateurs / filtres de fabrique :
utf8normalize(form)utf8category(category)
Le utf8normalize normalise l'entrée UTF-8 dans l'un de ces formats de normalisation :
C(ouNFC)D(ouNFD)KC(ouNFKC)KD(ouNFKD)
Le utf8category vérifie que la chaîne d'entrée est dans l'une des catégories suivantes (vous pouvez donc penser qu'elle a
plusieurs validateurs intégrés pour travailler avec la validation de chaînes UTF-8) :
LETTER_UPPERCASELETTER_LOWERCASELETTER_TITLECASELETTER_MODIFIERCASE_MAPPEDLETTER_OTHERLETTERMARK_NON_SPACINGMARK_SPACINGMARK_ENCLOSINGMARKNUMBER_DECIMALNUMBER_LETTERNUMBER_OTHERNUMBERPUNCTUATION_CONNECTORPUNCTUATION_DASHPUNCTUATION_OPENPUNCTUATION_CLOSEPUNCTUATION_INITIALPUNCTUATION_FINALPUNCTUATION_OTHERPUNCTUATIONSYMBOL_MATHSYMBOL_CURRENCYSYMBOL_MODIFIERSYMBOL_OTHERSYMBOLSEPARATOR_SPACESEPARATOR_LINESEPARATOR_PARAGRAPHSEPARATORCONTROLFORMATSURROGATEPRIVATE_USEUNASSIGNEDCOMPATIBILITYISUPPERISLOWERISALPHAISDIGITISALNUMISPUNCTISGRAPHISSPACEISPRINTISCNTRLISXDIGITISBLANKIGNORE_GRAPHEME_CLUSTER
Exemple
require "resty.validation.utf8"
local validation = require "resty.validation"
local valid, ts = validation:utf8category("LETTER_UPPERCASE")("TEST")
Extension resty.validation.injection
Cet ensemble de validateurs et de filtres est basé sur la formidable bibliothèque libinjection
de Nick Galbreath - un analyseur de token SQL / SQLI / XSS. Il nécessite mon wrapper LuaJIT FFI
lua-resty-injection pour fonctionner. Lorsque les exigences mentionnées
sont installées, le reste est facile. Pour utiliser cette extension, tout ce que vous devez faire est :
require "resty.validation.injection"
Cela patchera les adaptateurs qu'il fournira dans resty.validation, et ceux-ci sont actuellement :
sqli, retournefalsesi une injection SQL a été détectée, sinon retournetruexss, retournefalsesi une injection Cross-Site Scripting a été détectée, sinon retournetrue
Exemple
require "resty.validation.injection"
local validation = require "resty.validation"
local valid, ts = validation.sqli("test'; DELETE FROM users;")
local valid, ts = validation.xss("test <script>alert('XSS');</script>")
API
Je ne vais pas ici entrer dans les détails de tous les différents validateurs et filtres car ils suivent tous la même logique, mais je vais montrer quelques manières générales dont cela fonctionne.
validation._VERSION
Ce champ contient une version de la bibliothèque de validation, par exemple, sa valeur peut être "2.5" pour
la version 2.5 de cette bibliothèque.
validation booléenne, valeur/erreur...
Ces ... signifient la chaîne de validation. Cela est utilisé pour définir une seule chaîne de validateurs. Il n'y a pas de limite à
la longueur de la chaîne. Cela retournera toujours un booléen (si la validation est valide ou non). La deuxième valeur de retour sera
soit le nom du filtre qui n'a pas retourné true comme résultat de validation, soit la valeur filtrée.
local v = require "resty.validation"
-- Ce qui suit signifie, crée un validateur qui vérifie que l'entrée est :
-- 1. une chaîne
-- Si c'est le cas, alors supprime les espaces au début et à la fin de la chaîne :
-- 2. trim
-- Ensuite, vérifie que la longueur de la chaîne coupée est d'au moins 5 caractères (UTF-8) :
-- 3. minlen(5)
-- Et si tout va encore bien, convertit cette chaîne en majuscules
-- (le support UTF-8 n'est pas encore implémenté en majuscules) :
-- 4. upper
local myvalidator = v.string.trim:minlen(5).upper
-- Cet exemple retournera false et "minlen"
local valid, value = myvalidator(" \n\t a \t\n ")
-- Cet exemple retournera true et "ABCDE"
local valid, value = myvalidator(" \n\t abcde \t\n ")
Chaque fois que le validateur échoue et retourne false, vous ne devez pas utiliser la valeur retournée à d'autres fins que
le rapport d'erreur. Ainsi, la chaîne fonctionne comme ça. lua-resty-validation ne tentera rien si vous
spécifiez des chaînes qui ne seront jamais utilisées, telles que :
local v = require "resty.validation"
-- La valeur d'entrée ne peut jamais être à la fois une chaîne et un nombre en même temps :
local myvalidator = v.string.number:max(3)
-- Mais vous pourriez écrire cela comme ceci
-- (prendre l'entrée comme une chaîne, essayer de la convertir en nombre, et vérifier qu'elle est au plus 3) :
local myvalidator = v.string.tonumber:max(3)
Comme vous le voyez, c'est un moyen de définir des validateurs réutilisables uniques. Vous pouvez par exemple prédéfinir votre ensemble de chaînes de validateurs uniques de base et les stocker dans votre propre module à partir duquel vous pouvez réutiliser la même logique de validation dans différentes parties de votre application. Il est bon de commencer à définir des validateurs réutilisables uniques, puis de les réutiliser dans des validateurs de groupe.
Par exemple, disons que vous avez un module appelé validators :
local v = require "resty.validation"
return {
nick = v.string.trim:minlen(2),
email = v.string.trim.email,
password = v.string.trim:minlen(8)
}
Et maintenant, vous avez une fonction register quelque part dans votre application :
local validate = require "validators"
local function register(nick, email, password)
local vn, nick = validate.nick(nick)
local ve, email = validate.email(email)
local vp, password = validate.password(password)
if vn and ve and vp then
-- l'entrée est valide, faites quelque chose avec nick, email et password
else
-- l'entrée est invalide, nick, email et password contiennent les raisons d'erreur
end
end
Cela devient rapidement un peu sale, et c'est pourquoi nous avons des validateurs de groupe.
validation.table.new([table de validateurs])
Cette fonction est où la validation de groupe commence. Disons que vous avez un formulaire d'inscription qui vous demande un nick, un email (deux fois), et un mot de passe (deux fois).
Nous allons réutiliser les validateurs uniques, définis dans le module validators :
local v = require "resty.validation"
return {
nick = v.string.trim:minlen(2),
email = v.string.trim.email,
password = v.string.trim:minlen(8)
}
Maintenant, créons le validateur de groupe réutilisable dans le module forms :
local v = require "resty.validation"
local validate = require "validators"
-- D'abord, nous créons des validateurs uniques pour chaque champ de formulaire
local register = v.new{
nick = validate.nick,
email = validate.email,
email2 = validate.email,
password = validate.password,
password2 = validate.password
}
-- Ensuite, nous créons des validateurs de groupe pour l'email et le mot de passe :
register:compare "email == email2"
register:compare "password == password2"
-- Et enfin, nous retournons de ce module de formulaires
return {
register = register
}
Maintenant, quelque part dans votre application, vous avez cette fonction register :
local forms = require "forms"
local function register(data)
local valid, fields, errors = forms.register(data)
if valid then
-- l'entrée est valide, faites quelque chose avec les champs
else
-- l'entrée est invalide, faites quelque chose avec les champs et les erreurs
end
end
-- Et vous pourriez l'appeler comme :
register{
nick = "test",
email = "[email protected]",
email2 = "[email protected]",
password = "qwerty123",
password2 = "qwerty123"
}
Le grand avantage des validateurs de groupe est que vous pouvez encoder en JSON les champs et le tableau d'erreurs
et le retourner au client. Cela peut être utile lors de la construction d'une application à page unique
et vous avez besoin de signaler des erreurs côté serveur au client. Dans l'exemple ci-dessus, la variable fields
aura l'apparence suivante (valid serait vrai, et errors serait nil) :
{
nick = {
unvalidated = false,
value = "test",
input = "test",
name = "nick",
valid = true,
invalid = false,
validated = true
},
email = {
unvalidated = false,
value = "[email protected]",
input = "[email protected]",
name = "email",
valid = true,
invalid = false,
validated = true
},
email2 = {
unvalidated = false,
value = "[email protected]",
input = "[email protected]",
name = "email2",
valid = true,
invalid = false,
validated = true
},
password = {
unvalidated = false,
value = "qwerty123",
input = "qwerty123",
name = "password",
valid = true,
invalid = false,
validated = true
},
password2 = {
unvalidated = false,
value = "qwerty123",
input = "qwerty123",
name = "password2",
valid = true,
invalid = false,
validated = true
}
}
C'est génial pour un traitement ultérieur et pour renvoyer les champs encodés en JSON à l'application Javascript côté client, mais généralement, c'est une structure trop lourde à envoyer à la couche backend. Pour obtenir un tableau clé-valeur simple, nous pouvons appeler ce tableau de champs :
local data = fields()
La variable data contiendra maintenant :
{
nick = "test",
email = "[email protected]",
email2 = "[email protected]",
password = "qwerty123",
password2 = "qwerty123"
}
Maintenant, c'est quelque chose que vous pouvez envoyer par exemple dans Redis ou quelle que soit la couche de base de données (abstraction)
que vous avez. Mais, eh bien, cela ne s'arrête pas là, si par exemple votre couche de base de données s'intéresse uniquement à
nick, email et password (par exemple, supprimer ces doublons), vous pouvez même appeler le tableau data :
local realdata = data("nick", "email", "password")
Le realdata contiendra maintenant :
{
nick = "test",
email = "[email protected]",
password = "qwerty123"
}
field:accept(value)
Pour le champ, vous pouvez appeler accept qui fait ceci :
self.error = nil
self.value = value
self.valid = true
self.invalid = false
self.validated = true
self.unvalidated = false
field:reject(error)
Pour le champ, vous pouvez appeler reject qui fait ceci :
self.error = error
self.valid = false
self.invalid = true
self.validated = true
self.unvalidated = false
string field:state(invalid, valid, unvalidated)
Appeler state sur le champ est génial lorsque vous intégrez les résultats de validation dans par exemple un modèle HTML, tel que lua-resty-template. Voici un exemple utilisant lua-resty-template :
<form method="post">
<input class="{{ form.email:state('invalid', 'valid') }}"
name="email"
type="text"
placeholder="Email"
value="{{ form.email.input }}">
<button type="submit">Rejoindre</button>
</form>
Ainsi, en fonction de l'état du champ email, cela ajoutera une classe à l'élément d'entrée (par exemple, rendant la bordure de l'entrée rouge ou verte par exemple). Nous ne nous soucions pas de l'état non validé (par exemple, lorsque l'utilisateur a d'abord chargé la page et le formulaire).
Changements
Les changements de chaque version de ce module sont enregistrés dans le fichier Changes.md.
Voir aussi
- lua-resty-route — Bibliothèque de routage
- lua-resty-reqargs — Analyseur d'arguments de requête
- lua-resty-session — Bibliothèque de session
- lua-resty-template — Moteur de templating
GitHub
Vous pouvez trouver des conseils de configuration supplémentaires et de la documentation pour ce module dans le dépôt GitHub pour nginx-module-validation.