Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass id, but don't show it in the actual url

I am trying to get friendly urls. The friendly url at the moment are there like this:

localhost/customer/1/namehere

I want them like this:

localhost/customer/namehere

But still get want id (because I search my database with this id). What are my possibilities? And is this even possible?

This is my MapRoute:

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

This is how I link:

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

Thanks.

Update: Oh, it doesn't matter if the user changes it. I just want it to not show. So that the user can easily change the url to where they want to go. And don't have to worry about ids. (But I still need it. :))

like image 337
Vincent van der Linden Avatar asked Oct 09 '22 17:10

Vincent van der Linden


2 Answers

If I understood correctly your question, id is client id.

If you don't want to show your ID at all the solution is to not use a numeric id and do queries directly by client name. This is a little slower indeed but not so slow. You can get the id with a "reverse" query by client name, you can index by client name.

One possibility to avoid too much queries by username is to store the id in session or in an hidden field in a form using post (you can mix http post and http get without too much problems). You can store two fields: client name and client id, if client name match with the one in http get, you don't need to fetch the id. If they don't match, you can query the db for the id. The idea is to cache the id, so you search the id by client only once.

like image 50
Salvatore Previti Avatar answered Oct 13 '22 12:10

Salvatore Previti


You could for example encrypt the id + add some hash on it. In this way the user couldn't simply change it.

Or you could simply encrypt your id with a symmetric cipher, like AES or DES. The resulted id would be longer (because they work in blocks of 64-256 bits) and it wouldn't be possible to change a random character and obtain a valid id (technically with enough tries one could do it... Good luck!)

A code example

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

for id = 123 we have an encoded id = 4E-CD-80-9E-7E-FB-A7-B9-74-B6-3A-37-57-9C-BD-A9. I could have made it shorter by using Base64 or by removing the -, but in the second case the code would be a little more difficult. Without the -: D2B4F51E6577967A2262E3AE51F3EC74, in Base64: 0rT1HmV3lnoiYuOuUfPsdA==

Considering your use, probably DES is secure enough. With DES the id would be:

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

To use DES change all the Aes to DES and remove the BlockSize and KeySize lines.

like image 32
xanatos Avatar answered Oct 13 '22 10:10

xanatos