En mi educación me han dicho que es una idea defectuosa exponer las claves primarias reales (no solo las claves DB, sino todos los accesos primarios) al usuario.
Siempre pensé que era un problema de seguridad (porque un atacante podría intentar leer cosas que no fueran suyas).
Ahora tengo que verificar si el usuario tiene acceso de todos modos, ¿hay alguna razón diferente detrás?
Además, como mis usuarios tienen que acceder a los datos de todos modos, necesitaré tener una clave pública para el mundo exterior en algún punto intermedio. Ahora que la clave pública tiene los mismos problemas que la clave primaria, ¿no?
Se ha solicitado un ejemplo de por qué hacerlo de todos modos, así que aquí hay uno. Tenga en cuenta que la pregunta tiene que ver con el principio en sí, no solo si se aplica en este ejemplo. Las respuestas a otras situaciones son explícitamente bienvenidas.
La aplicación (web, móvil) que maneja la actividad, tiene múltiples IU y al menos una API automatizada para la comunicación entre sistemas (por ejemplo, el departamento de contabilidad quiere saber cuánto cobrar al cliente en función de lo que se ha hecho). La aplicación tiene varios clientes, por lo que la separación de sus datos (lógicamente, los datos se almacenan en el mismo DB) es imprescindible para el sistema. Se verificará la validez de cada solicitud sin importar qué.
La actividad es muy fina, por lo que está unida en algún objeto contenedor, llamémosla "Tarea".
Tres casos de uso:
- El usuario A quiere enviar al usuario B a alguna tarea, por lo que le envía un enlace (HTTP) para realizar alguna actividad allí.
- El usuario B debe salir del edificio para abrir la tarea en su dispositivo móvil.
- Contabilidad quiere cobrar al cliente por la Tarea, pero utiliza un sistema de contabilidad de terceros que carga automáticamente la Tarea / Actividad mediante un código que hace referencia a la REST - API de la Aplicación
Cada uno de los casos de uso requiere (o se hace más fácil si) que el agente tenga algún identificador direccionable para la Tarea y la Actividad.
ON UPDATE CASCADE
se hizo para eso (¿mysql específico?), aunque si el problema es la seguridad, entonces la verificación de acceso debería estar en el backend y no confiar en el usuario de todos modosRespuestas:
Exactamente. Tome el HTTP sin estado, que de otro modo no sabría qué recurso debería solicitar: expone la identificación de su pregunta
218306
en la URL. ¿Quizás se esté preguntando si un identificador expuesto puede ser predecible ?Los únicos lugares donde escuché una respuesta negativa a eso, usaron la lógica: "¡Pero pueden cambiar la ID en la URL!" . Entonces utilizaron GUID en lugar de implementar la autorización adecuada.
Me imagino una situación en la que no desea que sus identificadores sean predecibles: la recolección de recursos. Si tiene un sitio que aloja públicamente ciertos recursos en los que otros pueden ser interesantes, y los aloja como
/images/n.jpg
o/videos/n.mp4
donden
solo hay un número creciente, cualquiera que vea el tráfico hacia y desde su sitio web puede cosechar todos sus recursos.Entonces, para responder directamente a su pregunta: no, no está mal "exponer" directamente los identificadores que solo tienen significado para su programa, por lo general, incluso es necesario que su programa funcione con éxito.
fuente
No debe exponerlo porque las personas que lo vean comenzarán a usarlo como su 'número de cuenta', que NO es. Por ejemplo, para mi cuenta bancaria sé cuál es mi número de cuenta. Lo he memorizado, lo uso por teléfono con el servicio al cliente, lo uso al completar formularios para que otros bancos hagan transferencias, para documentos legales, para mi servicio de pago automático, etc., etc. No quiero para cambiar La clave principal (para mi cuenta) por otro lado, no lo sé ni lo veo.
El sistema que lo almacena cambia a lo largo de los años de un sistema a otro, a través de fusiones bancarias, actualizaciones y reemplazos del sistema, etc.
Las claves principales pueden cambiar a través de algunas de estas transformaciones, por lo que si nunca se ha expuesto, escrito o recordado por cualquier usuario habitual que '
Las claves sin significado comercial a menudo se denominan claves sustitutas y a menudo (pero no siempre) se utilizan como claves principales.
Por cierto, esto incluso ocurre internamente cuando las personas construyen interfaces y programas que hacen mal uso y exponen claves primarias y los hacen parte de tales sistemas en lugar de que solo hagan una cosa: identificar de forma única un registro de base de datos internamente. De hecho, aprendí lo anterior a través de un período de 6 años apoyando un sistema de almacenamiento de datos en un hospital.
fuente
Porque las claves principales son un detalle de implementación.
Si migra bases de datos, sus claves principales pueden cambiar debido al orden de inserción, eliminación de registros antiguos ... algunas razones diferentes. Si migra plataformas de bases de datos , es posible que ya no tenga una clave primaria real. Exponer la PK por encima de la capa de acceso a datos es una abstracción permeable, con todas las preocupaciones de acoplamiento que conlleva.
fuente
Esta es una respuesta combinada de las otras (también conocida como lo que he aprendido). Si tiene ganas de votar a este, al menos debe votar a uno de los otros tan bien como hicieron el trabajo real. Si está más interesado, lea las otras respuestas en su lugar.
No debe exponer la clave primaria de la base de datos, sino usar una clave sustituta
Nota: Su clave creada debe ser (un poco) humanamente comprensible ( Respuesta de Sqlvogels ).
Si su sistema no necesita 1. a 4. entonces no hay razón para no usar las bases de datos PK como su identificador público (varias de las respuestas). Además, la seguridad no es un problema aquí (varias de las respuestas).
fuente
Una de las razones por las que he encontrado es que, en la totalidad del tiempo, he visto a los usuarios finales solicitar que su identificador signifique algo (como tener un prefijo o un indicador del año en que se creó). Cambiar un PK es difícil, pero un sustituto es mucho más fácil.
Es probable que su clave principal sea algo que desea que indexe su base de datos por razones de rendimiento, y puede que a tiempo por razones técnicas la cambie, por ejemplo, de un número a un guid ... simplemente no sabe por qué razones las nuevas tecnologías o el conocimiento podría guiarte hacia abajo. Su paquete es su elemento técnico de datos, la clave pública es para el consumo de los usuarios finales.
fuente
InvoiceNumber
, lo que tiene un significado y puede ser cambiado por el cliente, pero también expongoInvoiceID
, que mi código utiliza para identificar de forma única la factura. No tiene que (y con mayor frecuencia no quiere ) dejar que la clave de usuario sea la clave de almacenamiento. Esta pregunta es sobre esto último.InvoiceNumber
(para diferentes inquilinos) pero tener diferentes claves principales: un punto (tipo de ) mencionado en la respuesta también.Para la mayoría de las aplicaciones es bastante esencial que expongas las claves a los usuarios. Para utilizar un sistema de información de manera efectiva, los usuarios de ese sistema normalmente necesitarán una forma de identificar la información dentro de él y relacionar esa información con algo en el mundo fuera de la base de datos. En términos de bases de datos relacionales, esos identificadores son claves.
Un patrón de diseño bien utilizado es crear una clave adicional, puramente "técnica" para las tablas de la base de datos como un medio de abstracción. Por ejemplo, para proporcionar una clave estable (relativamente inmutable) donde alguna clave alternativa está sujeta a cambios. Dichas claves técnicas generalmente no están expuestas a los usuarios finales porque hacerlo socava la abstracción prevista de los requisitos del usuario. No tiene nada que ver con la seguridad.
El problema / malentendido implícito en su pregunta se debe al uso inapropiado del término clave primaria . Una clave primaria es solo una entre varias claves "candidatas" (varios identificadores posibles en una tabla de base de datos). La clave primaria no requiere necesariamente ninguna propiedad fundamentalmente diferente a cualquier otra clave, por lo que las afirmaciones y los principios de diseño que se aplican específicamente a las claves primarias y no a otras claves son siempre sospechosos y, a menudo, incorrectos.
Dado que generalmente necesitará exponer una clave a su usuario, ¿cuál debería ser esa clave? Intenta que tus llaves sean familiares, simples y estables. La familiaridad y la simplicidad hacen que las claves sean fáciles de leer y recordar y ayudarán a evitar errores de entrada de datos. Estabilidad significa que la clave cambia con poca frecuencia, lo que también ayuda a evitar la posibilidad de una identificación errónea.
fuente
Esto es de un comentario sobre la respuesta de Greystone28 por CodeCaster. Es un ejemplo de lo que estás diciendo:
¿Qué propósito en su aplicación sirve para reproducir el InvoiceID?
Al exponer, supongo que quiere decir que el usuario puede verlo. Solo exponga si el usuario lo necesita para usar su aplicación. Podría ser utilizado por soporte técnico o algunas cosas administrativas. He trabajado con algunas aplicaciones que hacen esto. Hace que sea más fácil proporcionar soporte cuando conozco el registro específico en cuestión.
fuente
Es completamente normal que las entidades tengan un identificador único que esté expuesto al mundo exterior. Para algunos objetos, es posible encontrar un identificador que realmente tenga un significado (por ejemplo, número de factura) pero para otros no existe dicho identificador y, por lo tanto, debe generarse.
En aras de la coherencia y la legibilidad, considero que es una buena práctica que todas las entidades de un sistema utilicen exactamente el mismo tipo y nombre para su identificador. Normalmente este identificador estaría expuesto (
<type> getId()
) en alguna clase base abstracta.Por la misma razón, cada servicio en el sistema (por ejemplo, servicio de factura) debe proporcionar métodos idénticos para acceder a las entidades por su identificador. Normalmente, este método (
findById(<type> id)
) se heredaría de una interfaz de servicio genérica o una clase base.Este identificador no tiene que ser la clave principal de la entidad, pero puede ser una. Lo único que hay que asegurarse es que la estrategia de generación de claves produce identificadores razonablemente únicos (no necesariamente universalmente únicos, pero al menos dentro del sistema).
Si el sistema se migra más tarde (si es grande, según mi experiencia) a otra base de datos, no es un problema usar una estrategia diferente (no basada en claves primarias) para crear los identificadores siempre que la estrategia sea compatible con la original.
fuente
La clave principal está allí, solo como un identificador de la tupla (registro, fila) a la que intenta acceder como desarrollador. También se usa en integridad referencial (restricciones de clave externa), y quizás también tenga uno o más casos de uso.
Esencialmente, no hay nada malo en exponerlo a los usuarios, o incluso a los hackers. Porque no sé de un ataque que usa la clave primaria, por ejemplo.
Pero en seguridad, tenemos muchos principios (que aceptamos y no aprobamos) y debemos cumplirlos:
Y algunos otros principios. Lo que dicen esencialmente es que:
Si no necesita exponer sus datos, ¿por qué lo haría?
fuente