2011-10-21 8 views
5

Sto cercando di ottenere URL amichevole. L'url cordiale al momento non sono in questo modo:Passo id, ma non mostrano nella URL effettivo

localhost/cliente/1/namehere

Voglio che in questo modo:

localhost/cliente/namehere

Ma ancora ottenere voglia id (perché cerco il mio database con questo id). Quali sono le mie possibilità? Ed è anche possibile?

Questo è il mio rottaMappa:

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

Questo è come mi collego:

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

Grazie.

Aggiornamento: Oh, non importa se l'utente lo modifica. Voglio solo che non si mostri. In modo che l'utente possa facilmente cambiare l'URL in cui vogliono andare. E non devi preoccuparti degli ID. (Ma ho ancora bisogno. :))

+0

se ho capito la tua domanda - con questo modello 'localhost/customer/namehere' il tuo unico problema è passare 'ID'? in caso affermativo, perché non utilizzare la variabile di sessione? –

risposta

2

Se ho capito correttamente la tua domanda, id è id client.

Se non si desidera mostrare il proprio ID, la soluzione è di non utilizzare un id numerico e di eseguire direttamente le query in base al nome del cliente. Questo è un po 'più lento, ma non così lento. È possibile ottenere l'ID con una query "inversa" per nome client, è possibile indicizzare in base al nome del cliente.

Una possibilità per evitare troppe query per nome utente è quella di archiviare l'id in sessione o in un campo nascosto in un modulo utilizzando post (è possibile combinare post http e http senza troppi problemi). È possibile memorizzare due campi: nome client e ID client, se il nome client corrisponde a quello in http get, non è necessario recuperare l'ID. Se non corrispondono, puoi interrogare il db per l'id. L'idea è di memorizzare l'id nella cache, quindi si cerca l'ID dal client una sola volta.

2

Si potrebbe ad esempio cifrare il id + aggiungere un po 'di hash su di esso. In questo modo l'utente non poteva semplicemente cambiarlo.

Oppure puoi semplicemente crittografare il tuo id con un codice simmetrico, come AES o DES. Il risultato id sarebbe più lungo (perché lavorano in blocchi di 64-256 bit) e non sarebbe possibile modificare un carattere casuale e ottenere una valida id (tecnicamente con abbastanza tentativi si poteva farlo ... Buona fortuna!)

un codice esempio

// 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); 

per id = 123 abbiamo un codificato id = 4E-CD-80-9E-7E-FB-A7-B9-74-B6-3A-37-57-9C-BD-A9. Ho potuto fare più breve utilizzando Base64 o rimuovendo il -, ma nel secondo caso il codice sarebbe un po 'più difficile. Senza il -: D2B4F51E6577967A2262E3AE51F3EC74, in Base64: 0rT1HmV3lnoiYuOuUfPsdA==

Considerando l'utilizzo, probabilmente DES è abbastanza sicura. Con DES la id sarebbe:

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

Per utilizzare DES cambiare tutti i Aes per DES e rimuovere le linee BlockSize e KeySize.

+0

Oh, non importa se l'utente lo cambia. Voglio solo che non si mostri. In modo che l'utente possa facilmente cambiare l'URL in cui vogliono andare. –

+0

@VincentvanderLinden Se vuoi proteggere solo contro "cambiando", allora devi solo cancellarlo usando del sale segreto. Quindi il tuo link sarebbe: 123XXXXXXXX dove la X è l'hash. Quindi puoi controllare se l'hash è stato generato da te. Se vuoi anche proteggerlo dalla "visualizzazione" (ad esempio, non vuoi che il tuo utente sappia quanti clienti ci sono), allora cripta + hash. Oppure puoi semplicemente crittografarlo con (per esempio) ECC (crittografia delle curve ellittiche). Quindi l'output sarebbe piuttosto lungo e trovare l'output "corretto" "a caso" sarebbe impossibile. – xanatos

+0

@VincentvanderLinden supponiamo che il tuo collegamento sia questo 'localhost/customer/namehere? Id = 1515870811'. Riesci a indovinare il vero ID (non usare un algoritmo così stupido - è stato generato con 1^0x5a5a5a5a) –

0

Se si desidera che il risultato sia deterministico devi passare una combinazione unica di parametri. Nel tuo caso, potresti usare il parametro "customername" con un numero successivo per i clienti con lo stesso nome (dovrai memorizzare quel numero nel tuo db insieme al nome del cliente).Per esempio:

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 
... 

la maschera percorso sarebbe qualcosa di simile customer/{customername}_{customerIndex}/.

Problemi correlati