Cómo consultar correctamente el campo JSONB de Postgres en Vapor/Fluent.
Tengo una tabla con algunas columnas jsonb creadas por una migración como esta:
public func prepare(on database: Database) -> EventLoopFuture<void> {
return database.schema(MyTable.schema)
.id()
.field(.metadata, .custom("JSONB"), .required)
.create()
}
Estoy tratando de filtrar una consulta en el campo jsonb. Lo siguiente es una interpolación de cadena simple que funciona.
//jsonFilters es un diccionario de pares clave-valor para los cuales queremos filtrar en el campo jsonb
var query = MyTable.query(on: db)
var filterString = ""
var cycleCount = 0;
jsonFilters.forEach({
(key, value) in
filterString +=
"metadata->>'\(key)' = '\(value)' "
cycleCount+=1
if(cycleCount < filter.metadata!.count) {
filterString += " AND "
}
})
query = query.filter(.custom(metadataString))
// También filtrar en algo más.
query = query.filter(....)
Sin embargo, esto no es seguro y es vulnerable a la inyección de SQL. ¿Hay alguna manera de unir los argumentos de filtro utilizando SQLQueryString, por ejemplo? Debería funcionar junto con el resto del filtro regular. (Última línea en el código)
davy.ai
Sí, es posible vincular los argumentos del filtro utilizando SQLQueryString para evitar vulnerabilidades de inyección SQL. Puede modificar su código de la siguiente manera:
En este código actualizado, se crea una matriz
bindings
para almacenar los valores que deben ser vinculados a la consulta. La cadena de filtro se modifica para utilizar marcadores de posición:key
y:value
que corresponden a la posición del valor en la matriz de vinculación. Finalmente, se utilizaSQLQueryString
para crear una consulta correctamente formada con los vinculables. Esto garantiza que los valores estén saneados y seguros contra ataques de inyección SQL.