2011-10-21 9 views
5

Estoy tratando de obtener URLs amigables. La URL amigable en este momento hay como esto:Pase la identificación, pero no la muestre en la url real

localhost/cliente/1/namehere

los quiero de esta manera:

localhost/cliente/namehere

Pero aún así obtener el ID de querer (porque busco en mi base de datos con esta identificación). ¿Cuáles son mis posibilidades? ¿Y esto es posible?

Esta es mi MapRoute:

context.MapRoute(
      "Customer_Default", 
      "customer/{customername}/", 
      new { controller = "customer", action = "view", id = "", customername = "" } 
     ); 

Así es como me enlace:

@Html.ActionLink(c.Bedrijfsnaam, "view", "customer", new { id = c.Klantnummer, customername = UrlEncoder.ToFriendlyUrl(c.Bedrijfsnaam) }, null) 

Gracias.

Actualización: Oh, no importa si el usuario lo cambia. Solo quiero que no se muestre. Para que el usuario pueda cambiar fácilmente la URL a donde quiere ir. Y no tiene que preocuparse por los ids. (Pero todavía lo necesito. :))

+0

si entendí su pregunta - con este patrón 'localhost/customer/namehere' ¿su único problema es pasar el' ID'? si es así, ¿por qué no usar la variable de sesión? –

Respuesta

2

Si he entendido correctamente su pregunta, id es la identificación del cliente.

Si no desea mostrar su ID en absoluto, la solución es no utilizar una identificación numérica y hacer consultas directamente por nombre del cliente. Esto es un poco más lento pero no tan lento. Puede obtener la identificación con una consulta "inversa" por nombre del cliente, puede indexar por nombre del cliente.

Una posibilidad de evitar demasiadas consultas por nombre de usuario es almacenar la identificación en sesión o en un campo oculto en un formulario mediante publicación (puede mezclar http post y http obtener sin demasiados problemas). Puede almacenar dos campos: el nombre del cliente y el ID del cliente, si el nombre del cliente coincide con el de http get, no necesita recuperar el ID. Si no coinciden, puede consultar el archivo db para la identificación. La idea es almacenar en caché la identificación, por lo que busca el ID por cliente solo una vez.

2

Podría por ejemplo encriptar el id + agregar algo de hash en él. De esta forma, el usuario no podría simplemente cambiarlo.

O simplemente puede encriptar su id con un cifrado simétrico, como AES o DES. El resultado id sería más largo (porque funcionan en bloques de 64-256 bits) y no sería posible cambiar un carácter aleatorio y obtener un id válido (técnicamente con suficientes intentos uno podría hacerlo ... ¡Buena suerte!)

un código de ejemplo

// Generate key. You do it once and save the key in the web.config or in the code 
var encryptorForGenerateKey = Aes.Create(); 
encryptorForGenerateKey.BlockSize = 128; 
encryptorForGenerateKey.KeySize = 128; 
encryptorForGenerateKey.GenerateKey(); 
encryptorForGenerateKey.GenerateIV(); 

var key = encryptorForGenerateKey.Key; 
var iv = encryptorForGenerateKey.IV; 

// Encrypt 

var encryptor = Aes.Create(); 
var encryptorTransformer = encryptorForGenerateKey.CreateEncryptor(key, iv); 

int id = 123; 
var bytes = BitConverter.GetBytes(id); 
var encrypted = encryptorTransformer.TransformFinalBlock(bytes, 0, bytes.Length); 
var encryptedString = BitConverter.ToString(encrypted); 

Console.WriteLine(encryptedString); 

// Decrypt 

var decryptor = Aes.Create(); 
var decryptorTransformer = decryptor.CreateDecryptor(key, iv); 

String[] arr = encryptedString.Split('-'); 
byte[] encrypted2 = new byte[arr.Length]; 
for (int i = 0; i < arr.Length; i++) 
{ 
    encrypted2[i] = Convert.ToByte(arr[i], 16); 
} 

// If the block is irregular there is the possibility TransformFinalBlock will throw 

var result = decryptorTransformer.TransformFinalBlock(encrypted2, 0, encrypted2.Length); 

if (result.Length != sizeof(int)) 
{ 
    throw new Exception(); 
} 

var id2 = BitConverter.ToInt32(result, 0); 

para id = 123 hemos un codificada id = 4E-CD-80-9E-7E-FB-A7-B9-74-B6-3A-37-57-9C-BD-A9. Pude haberlo acortado usando Base64 o quitando el -, pero en el segundo caso el código sería un poco más difícil. Sin la -: D2B4F51E6577967A2262E3AE51F3EC74, en base 64: 0rT1HmV3lnoiYuOuUfPsdA==

Teniendo en cuenta su uso, probablemente DES es lo suficientemente seguro. Con el DES id sería:

F2-54-4B-CE-23-83-96-C2 // With - 
F2544BCE238396C2 // Without - 
8lRLziODlsI= // Base64 

Para utilizar DES cambiar todos los Aes a DES y retirar los BlockSize y KeySize líneas.

+0

Oh, no importa si el usuario lo cambia. Solo quiero que no se muestre. Para que el usuario pueda cambiar fácilmente la URL a donde quiere ir. –

+0

@VincentvanderLinden Si quiere proteger solo contra el "cambio", solo necesita usar hash con alguna sal secreta. Entonces su enlace sería: 123XXXXXXXX donde las X son el hash. Luego puedes verificar si hash has generado el hash. Si incluso desea protegerlo de la "visualización" (por ejemplo, no desea que su usuario sepa cuántos clientes hay), cifre + hash. O simplemente puede encriptarlo con (por ejemplo) ECC (encriptación de curvas elípticas). Entonces la salida sería bastante larga y sería imposible encontrar la salida "correcta" "al azar". – xanatos

+0

@VincentvanderLinden supongamos que su enlace es este 'localhost/customer/namehere? Id = 1515870811'. ¿Puedes adivinar la identificación real. (No uses un algoritmo tan estúpido? Se generó con 1^0x5a5a5a5a) –

0

Si desea que el resultado sea determinista, debe pasar una combinación única de parámetros. En su caso, podría usar el parámetro "nombre de cliente" con un número después para los clientes con el mismo nombre (deberá almacenar ese número en su base de datos junto con el nombre del cliente).Por ejemplo:

localhost/customer/Aaron_Babichev - for the first customer with name Aaron Babichev 
localhost/customer/Aaron_Babichev_2 - for the second customer with name Aaron Babichev 
... 

Su máscara ruta sería algo así como customer/{customername}_{customerIndex}/.

Cuestiones relacionadas