validación: Biblioteca de Validación (Validación y Filtrado de Entrada) para Lua y nginx-module-lua
Instalación
Si no has configurado la suscripción al repositorio RPM, regístrate. Luego puedes proceder con los siguientes pasos.
CentOS/RHEL 7 o 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
Para usar esta biblioteca Lua con NGINX, asegúrate de que nginx-module-lua esté instalado.
Este documento describe lua-resty-validation v2.7 lanzado el 25 de agosto de 2017.
lua-resty-validation es una biblioteca de validación y filtrado encadenable y extensible para Lua y OpenResty.
Hola Mundo con 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"
-- Los validadores pueden ser reutilizados
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"
-- Los validadores pueden hacer filtrado (es decir, modificar el valor que se está validando)
-- valid = true, s = "¡HOLA MUNDO!"
local valid, s = validation.string.upper "hello world!"
-- Puedes extender la biblioteca de validación con tus propios validadores y filtros...
validation.validators.capitalize = function(value)
return true, value:gsub("^%l", string.upper)
end
-- ... y luego usarlo
local valid, e = validation.capitalize "abc" -- valid = true, e = "Abc"
-- También puedes validar en grupo muchos valores
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("todos los campos del grupo son válidos")
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
-- Incluso puedes llamar a fields para obtener una tabla simple de nombre y valor
-- (en ese caso, todos los `nil` también son eliminados)
-- Por defecto, esto solo devuelve los nombres y valores de los campos válidos:
local data = fields()
local data = fields "valid"
-- Para obtener solo los nombres y valores de los campos inválidos llama:
local data = fields "invalid"
-- Para obtener solo los nombres y valores de los campos validados llama (ya sean válidos o no):
local data = fields "validated"
-- Para obtener solo los nombres y valores de los campos no validados llama (ya sean válidos o no):
local data = fields "unvalidated"
-- Para obtener todos, llama:
local data = fields "all"
-- O combina:
local data = fields("valid", "invalid")
-- Esto no se detiene aquí. También puedes querer obtener solo algunos campos por su nombre.
-- Puedes hacer eso llamando (devuelve una tabla):
local data = data{ "artist" }
Validadores y Filtros Incorporados
lua-resty-validation viene con varios validadores incorporados, y el proyecto está abierto a contribuciones de más validadores.
Validadores y Filtros sin Argumentos
Los validadores de tipo se pueden usar para validar el tipo del valor validado. Estos validadores son validadores sin argumentos (llámalos con punto .):
nullo["nil"](ya que nil es una palabra clave reservada en Lua)booleannumberstringtableuserdatafunco["function"](ya que function es una palabra clave reservada en Lua)callable(ya sea una función o una tabla con el metamétodo__call)threadintegerfloatfile(io.type(value) == 'file')
Filtros de conversión de tipo:
tostringtonumbertointegertoboolean
Otros filtros:
tonilotonullabsinfnanfinitepositivenegativeloweruppertrimltrimrtrimreverseemailoptional
Ejemplo
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('¡Hola, Mundo!')
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)
Validadores y Filtros de Fábrica de Validación
La fábrica de validación consiste en diferentes validadores y filtros utilizados para validar o filtrar el valor (llámalos con dos puntos :):
type(t), valida que el valor sea del tipot(ver Validadores de Tipo)nil()o["null"](), verifica que el tipo de valor seanilboolean(), verifica que el tipo de valor seabooleannumber(), verifica que el tipo de valor seanumberstring(), verifica que el tipo de valor seastringtable(), verifica que el tipo de valor seatableuserdata(), verifica que el tipo de valor seauserdatafunc()o["function"](), verifica que el tipo de valor seafunctioncallable(), verifica que el valor sea callable (es decir, una función o una tabla con el metamétodo__call)thread(), verifica que el tipo de valor seathreadinteger(), verifica que el tipo de valor seaintegerfloat(), verifica que el tipo de valor seafloatfile(), verifica que el tipo de valor seafile(io.type(value) == 'file')abs(), filtra el valor y devuelve el valor absoluto (math.abs)inf(), verifica que el valor seainfo-infnan(), verifica que el valor seananfinite(), verifica que el valor no seanan,info-infpositive(), valida que el valor sea positivo (> 0)negative(), valida que el valor sea negativo (< 0)min(min), valida que el valor sea al menosmin(>=)max(max), valida que el valor sea como máximomax(<=)between(min[, max = min]), valida que el valor esté entreminymaxoutside(min[, max = min]), valida que el valor no esté entreminymaxdivisible(number), valida que el valor sea divisible pornumberindivisible(number), valida que el valor no sea divisible pornumberlen(min[, max = min]), valida que la longitud del valor sea exactamentemino esté entreminymax(UTF-8)minlen(min), valida que la longitud del valor sea al menosmin(UTF-8)maxlen(max), valida que la longitud del valor sea como máximomax(UTF-8)equals(equal)oequal(equal), valida que el valor sea exactamente algounequals(equal)ounequal(equal), valida que el valor no sea exactamente algooneof(...), valida que el valor sea igual a uno de los argumentos suministradosnoneof(...), valida que el valor no sea igual a ninguno de los argumentos suministradosmatch(pattern[, init]), valida que el valor coincida (string.match) con el patrónunmatch(pattern[, init]), valida que el valor no coincida (string.match) con el patróntostring(), convierte el valor a cadenatonumber([base]), convierte el valor a númerotointeger(), convierte el valor a enterotoboolean(), convierte el valor a booleano (usandonot not value)tonil()otonull(), convierte el valor a nillower(), convierte el valor a minúsculas (el soporte para UTF-8 aún no está implementado)upper(), convierte el valor a mayúsculas (el soporte para UTF-8 aún no está implementado)trim([pattern]), recorta espacios en blanco (puedes usar un patrón también) de la izquierda y de la derechaltrim([pattern]), recorta espacios en blanco (puedes usar un patrón también) de la izquierdartrim([pattern]), recorta espacios en blanco (puedes usar un patrón también) de la derechastarts(starts), verifica si la cadena comienza constartsends(ends), verifica si la cadena termina conendsreverse, invierte el valor (cadena o número) (UTF-8)coalesce(...), si el valor es nil, devuelve el primer valor no nil pasado como argumentoemail(), valida que el valor sea una dirección de correo electrónicocall(function), valida / filtra el valor contra un validador / filtro en línea personalizadooptional([default]), detiene la validación si el valor es una cadena vacía""onily devuelvetrue, y ya sea,defaultovalue
Validadores de Fábrica de Validación Condicional
Para todos los Validadores de Fábrica de Validación hay una versión condicional que siempre valida como verdadera, pero donde puedes reemplazar el valor real dependiendo de si el validador original validó. Oye, esto es más fácil de mostrar que de decir:
local validation = require "resty.validation"
-- ok == true, value == "Sí, el valor es nil"
local ok, value = validation:ifnil(
"Sí, el valor es nil",
"No, no proporcionaste un valor nil")(nil)
-- ok == true, value == "No, no proporcionaste un valor nil"
local ok, value = validation:ifnil(
"Sí, el valor es nil",
"No, no proporcionaste un valor nil")("non nil")
-- ok == true, value == "Sí, el número está entre 1 y 10"
local ok, value = validation:ifbetween(1, 10,
"Sí, el número está entre 1 y 10",
"No, el número no está entre 1 y 10")(5)
-- ok == true, value == "No, el número no está entre 1 y 10"
local ok, value = validation:ifbetween(1, 10,
"Sí, el número está entre 1 y 10",
"No, el número no está entre 1 y 10")(100)
Los últimos 2 argumentos para los validadores de fábrica de validación condicional son los valores truthy y falsy. Cada otro argumento se pasa al validador de fábrica de validación real.
Validadores de Grupo
lua-resty-validation actualmente soporta algunos validadores predefinidos:
compare(comparison), compara dos campos y establece los campos como inválidos o válidos de acuerdo a la comparaciónrequisite{ fields }, al menos uno de los campos requeridos es necesario, incluso si por sí mismos son opcionalesrequisites({ fields }, number), al menosnumberde campos requeridos son necesarios (por defecto todos ellos)call(function), llama a una función de validación de grupo personalizada (o en línea)
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)
-- o group:requisites{ "text", "html" }
local valid, fields, errors = group{ text = "", html = "" }
group:call(function(fields)
if fields.text.value == "hello" then
fields.text:reject "el texto no puede ser 'hello'"
fields.html:reject "debido a que el texto fue 'hello', este campo también se invalida"
end
end)
Puedes usar operadores relacionales normales de Lua en el validador de grupo compare:
<><=>===~=
requisite y requisites verifican si el valor del campo es nil o "" (cadena vacía). Con requisite, si todos los campos especificados son nil o "", entonces todos los campos son inválidos (siempre que no fueran por sí mismos inválidos), y si al menos uno de los campos es válido, entonces todos los campos son válidos. requisites funciona de la misma manera, pero allí puedes definir el número de campos que deseas que tengan un valor que no sea nil y no sea una cadena vacía "". Estos proporcionan validación condicional en el sentido de:
- Tengo (dos o más) campos
- Todos ellos son opcionales
- Al menos uno / número definido de campos debe estar lleno, pero no me importa cuál, siempre que haya al menos uno / número definido de campos llenos
Validadores de Detención
Los validadores de detención, como optional, son como validadores normales, pero en lugar de devolver true o false como resultado de validación O como un valor filtrado, puedes devolver validation.stop. Este valor también se puede usar dentro de validadores condicionales y en validadores que admiten valores predeterminados. Aquí está cómo se implementa el validador optional:
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
Estos son aproximadamente equivalentes:
-- Ambos devuelven: true, "default" (detienen el procesamiento :minlen(10) en entradas nil y "")
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)
Filtrando Valor y Estableciendo el Valor a nil
La mayoría de los validadores, que no están filtrando el valor, solo devuelven true o false como resultado. Eso significa que no hay forma de señalar a resty.validation que realmente establezca el valor a nil. Así que hay un trabajo alrededor, puedes devolver validation.nothing como un valor, y eso cambiará el valor a nil, por ejemplo, el validador incorporado tonil se implementa en realidad así (pseudo):
function()
return true, validation.nothing
end
Validadores y Filtros Personalizados (En Línea)
A veces puedes tener validadores / filtros únicos que no estás usando en otros lugares, o que solo deseas proporcionar rápidamente un validador / filtro adicional para un caso específico. Para facilitar esto, introdujimos el método de fábrica call con lua-resty-validation 2.4. Aquí hay un ejemplo:
validation:call(function(value)
-- ahora valida / filtra el valor y devuelve los resultados
-- aquí solo devolvemos false (es decir, haciendo que la validación falle)
return false
end)("Verifica este valor"))
(por supuesto, no necesita ser una función en línea, ya que en Lua todas las funciones son ciudadanos de primera clase y pueden pasarse como parámetros)
Extensiones de Validadores Incorporados
Actualmente lua-resty-validation tiene soporte para dos extensiones o complementos que puedes habilitar:
resty.validation.ngxresty.validation.tzresty.validation.utf8
Estos son algo que puedes considerar si deseas construir tu propia extensión de validador. Si lo haces, y crees que sería utilizable para otros también, asegúrate de enviar tu extensión como una solicitud de extracción para su inclusión en este proyecto, muchas gracias, ;-).
Extensión resty.validation.ngx
Como su nombre indica, este conjunto de extensiones de validador requiere OpenResty (o el módulo Lua Nginx al menos). Para usar esta extensión, todo lo que necesitas hacer es:
require "resty.validation.ngx"
Esto parcheará los adaptadores que proporcionará en resty.validation, y estos son actualmente:
escapeuriunescapeuribase64encbase64deccrc32shortcrc32longcrc32md5
(hay tanto versión de fábrica como versión sin argumentos de estos)
También hay un coincididor regex en la extensión ngx que utiliza ngx.re.match, y md5 parametrizado:
regex(regex[, options])md5([bin])
Ejemplo
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/")
Extensión resty.validation.tz
Este conjunto de validadores y filtros se basa en la gran biblioteca luatz de @daurnimator, que es una biblioteca para la manipulación de tiempo y fecha. Para usar esta extensión, todo lo que necesitas hacer es:
require "resty.validation.tz"
Esto parcheará los adaptadores que proporcionará en resty.validation, y estos son actualmente:
totimetabletotimestamp
(hay tanto versión de fábrica como versión sin argumentos de estos)
Los filtros totimestamp y totimetable funcionan muy bien con campos de entrada de fecha y datetime de HTML5. Como su nombre indica, totimetable devuelve timetable de luatz y totimestamp devuelve segundos desde la época unix (1970-01-01) como un número Lua.
Ejemplo
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")
Extensión resty.validation.utf8
Este conjunto de validadores y filtros se basa en la gran biblioteca utf8rewind de Quinten Lansu - una biblioteca del sistema escrita en C diseñada para extender las funciones de manejo de cadenas predeterminadas con soporte para texto codificado en UTF-8. Necesita mi envoltura FFI de LuaJIT lua-resty-utf8rewind para funcionar. Cuando se instalan los requisitos mencionados, el resto es fácil. Para usar esta extensión, todo lo que necesitas hacer es:
require "resty.validation.utf8"
Esto parcheará los adaptadores que proporcionará en resty.validation, y estos son actualmente:
utf8upperutf8lowerutf8title
(hay tanto versión de fábrica como versión sin argumentos de estos)
También hay algunos validadores / filtros de fábrica:
utf8normalize(form)utf8category(category)
El utf8normalize normaliza la entrada UTF-8 a uno de estos formatos de normalización:
C(oNFC)D(oNFD)KC(oNFKC)KD(oNFKD)
El utf8category verifica que la cadena de entrada esté en una de las siguientes categorías (así que, puedes pensar que tiene múltiples validadores incorporados para trabajar con la validación de cadenas 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
Ejemplo
require "resty.validation.utf8"
local validation = require "resty.validation"
local valid, ts = validation:utf8category("LETTER_UPPERCASE")("TEST")
Extensión resty.validation.injection
Este conjunto de validadores y filtros se basa en la gran biblioteca libinjection de Nick Galbreath - un analizador de tokenización de SQL / SQLI / XSS. Necesita mi envoltura FFI de LuaJIT lua-resty-injection para funcionar. Cuando se instalan los requisitos mencionados, el resto es fácil. Para usar esta extensión, todo lo que necesitas hacer es:
require "resty.validation.injection"
Esto parcheará los adaptadores que proporcionará en resty.validation, y estos son actualmente:
sqli, devuelvefalsesi se detectó inyección SQL, de lo contrario devuelvetruexss, devuelvefalsesi se detectó inyección de Cross-Site Scripting, de lo contrario devuelvetrue
Ejemplo
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
No voy a entrar en detalles sobre todos los diferentes validadores y filtros porque todos siguen la misma lógica, pero mostraré algunas formas generales de cómo funciona esto.
validation._VERSION
Este campo contiene una versión de la biblioteca de validación, por ejemplo, su valor puede ser "2.5" para la versión 2.5 de esta biblioteca.
validación booleana, valor/error...
Ese ... significa la cadena de validación. Esto se usa para definir una única cadena de validador. No hay límite en la longitud de la cadena. Siempre devolverá un booleano (si la validación es válida o no). El segundo valor de retorno será ya sea el nombre del filtro que no devolvió true como resultado de validación, o el valor filtrado.
local v = require "resty.validation"
-- Lo siguiente significa, crear un validador que verifica que la entrada sea:
-- 1. cadena
-- Si lo es, entonces recorta los espacios en blanco del principio y el final de la cadena:
-- 2. trim
-- Luego verifica que la longitud de la cadena recortada sea al menos 5 caracteres (UTF-8):
-- 3. minlen(5)
-- Y si todo sigue bien, convierte esa cadena a mayúsculas
-- (el soporte para UTF-8 aún no está implementado en mayúsculas):
-- 4. upper
local myvalidator = v.string.trim:minlen(5).upper
-- Este ejemplo devolverá false y "minlen"
local valid, value = myvalidator(" \n\t a \t\n ")
-- Este ejemplo devolverá true y "ABCDE"
local valid, value = myvalidator(" \n\t abcde \t\n ")
Cada vez que el validador falla y devuelve false, no debes usar el valor devuelto para otros propósitos que no sean la notificación de errores. Así que, la cadena funciona de esa manera. lua-resty-validation no intentará hacer nada si especificas cadenas que nunca se usarán, como:
local v = require "resty.validation"
-- El valor de entrada nunca puede ser tanto cadena como número al mismo tiempo:
local myvalidator = v.string.number:max(3)
-- Pero podrías escribir esto así
-- (toma la entrada como una cadena, intenta convertirla a número y verifica que sea como máximo 3):
local myvalidator = v.string.tonumber:max(3)
Como ves, esta es una forma de definir validadores reutilizables únicos. Puedes, por ejemplo, predefinir tu conjunto de cadenas de validadores básicos y almacenarlo en tu propio módulo desde el cual puedes reutilizar la misma lógica de validación en diferentes partes de tu aplicación. Es una buena idea comenzar definiendo validadores reutilizables únicos, y luego reutilizarlos en validadores de grupo.
Por ejemplo, digamos que tienes un módulo llamado validators:
local v = require "resty.validation"
return {
nick = v.string.trim:minlen(2),
email = v.string.trim.email,
password = v.string.trim:minlen(8)
}
Y ahora tienes una función register en algún lugar de tu aplicación:
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
-- la entrada es válida, haz algo con nick, email y password
else
-- la entrada es inválida, nick, email y password contienen las razones de error
end
end
Esto rápidamente se vuelve un poco desordenado, y por eso tenemos validadores de grupo.
validación.table.new([tabla de validadores])
Esta función es donde comienza la validación de grupo. Supongamos que tienes un formulario de registro que te pide un nick, un email (el mismo dos veces) y una contraseña (la misma dos veces).
Reutilizaremos los validadores únicos, definidos en el módulo validators:
local v = require "resty.validation"
return {
nick = v.string.trim:minlen(2),
email = v.string.trim.email,
password = v.string.trim:minlen(8)
}
Ahora, vamos a crear el validador de grupo reutilizable en el módulo forms:
local v = require "resty.validation"
local validate = require "validators"
-- Primero creamos validadores únicos para cada campo del formulario
local register = v.new{
nick = validate.nick,
email = validate.email,
email2 = validate.email,
password = validate.password,
password2 = validate.password
}
-- A continuación, creamos validadores de grupo para email y contraseña:
register:compare "email == email2"
register:compare "password == password2"
-- Y finalmente devolvemos desde este módulo de formularios
return {
register = register
}
Ahora, en algún lugar de tu aplicación tienes esta función register:
local forms = require "forms"
local function register(data)
local valid, fields, errors = forms.register(data)
if valid then
-- la entrada es válida, haz algo con los campos
else
-- la entrada es inválida, haz algo con los campos y errores
end
end
-- Y podrías llamarla así:
register{
nick = "test",
email = "[email protected]",
email2 = "[email protected]",
password = "qwerty123",
password2 = "qwerty123"
}
Lo grandioso de los validadores de grupo es que puedes codificar en JSON la tabla de campos y errores y devolverla al cliente. Esto puede ser útil al construir una aplicación de una sola página y necesitas informar errores del lado del servidor al cliente. En el ejemplo anterior, la variable fields se verá así (valid sería verdadero, y errors sería 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
}
}
Esto es genial para un procesamiento posterior y enviar los campos como JSON codificado de vuelta a la aplicación Javascript del lado del cliente, pero generalmente esta es una construcción demasiado pesada para ser enviada a la capa de backend. Para obtener una tabla simple de clave-valor, podemos llamar a esta tabla de campos:
local data = fields()
La variable data ahora contendrá:
{
nick = "test",
email = "[email protected]",
email2 = "[email protected]",
password = "qwerty123",
password2 = "qwerty123"
}
Ahora esto es algo que puedes enviar, por ejemplo, en Redis o cualquier capa de base de datos (abstracción) que tengas. Pero, bueno, esto no se detiene aquí, si digamos que tu capa de base de datos solo está interesada en nick, email y password (por ejemplo, eliminar esos duplicados), incluso puedes llamar a la tabla data:
local realdata = data("nick", "email", "password")
La realdata ahora contendrá:
{
nick = "test",
email = "[email protected]",
password = "qwerty123"
}
field:accept(value)
Para el campo puedes llamar a accept que hace esto:
self.error = nil
self.value = value
self.valid = true
self.invalid = false
self.validated = true
self.unvalidated = false
field:reject(error)
Para el campo puedes llamar a reject que hace esto:
self.error = error
self.valid = false
self.invalid = true
self.validated = true
self.unvalidated = false
string field:state(invalid, valid, unvalidated)
Llamar a state en el campo es genial cuando se incrustan los resultados de validación dentro de, digamos, una plantilla HTML, como lua-resty-template. Aquí hay un ejemplo usando 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">Unirse</button>
</form>
Así que dependiendo del estado del campo de email, esto añadirá una clase al elemento de entrada (por ejemplo, haciendo que el borde de la entrada sea rojo o verde, por ejemplo). No nos importa el estado no validado (por ejemplo, cuando el usuario cargó la página y el formulario por primera vez).
Cambios
Los cambios de cada lanzamiento de este módulo se registran en el archivo Changes.md.
Véase También
- lua-resty-route — Biblioteca de enrutamiento
- lua-resty-reqargs — Analizador de argumentos de solicitud
- lua-resty-session — Biblioteca de sesión
- lua-resty-template — Motor de plantillas
GitHub
Puedes encontrar consejos de configuración adicionales y documentación para este módulo en el repositorio de GitHub para nginx-module-validation.