Передайте идентификатор, но не показывайте его в фактическом URL - PullRequest
5 голосов
/ 21 октября 2011

Я пытаюсь получить дружеские ссылки.Дружеский URL на данный момент существует примерно так:

localhost / customer / 1 / namehere

Я хочу их вот так:

localhost / customer / namehere

Но все равно получите идентификатор (потому что я ищу в своей базе данных с этим идентификатором).Каковы мои возможности?И возможно ли это вообще?

Это мой MapRoute:

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

Вот как я связываю:

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

Спасибо.

Обновление: О, это не имеет значения, если пользователь меняет его.Я просто хочу, чтобы это не показывалось.Так что пользователь может легко изменить URL-адрес, куда он хочет пойти.И не нужно беспокоиться об идентификаторах.(Но мне все еще это нужно. :))

Ответы [ 3 ]

2 голосов
/ 21 октября 2011

Если я правильно понял ваш вопрос, id - это идентификатор клиента.

Если вы вообще не хотите показывать свой идентификатор, решение состоит в том, чтобы не использовать числовой идентификатор и выполнять запросы непосредственно по имени клиента. Это немного медленнее, но не так медленно. Вы можете получить идентификатор с помощью «обратного» запроса по имени клиента, вы можете индексировать по имени клиента.

Одной из возможностей избежать слишком большого количества запросов по имени пользователя является сохранение идентификатора в сеансе или в скрытом поле в форме с использованием записи (вы можете смешивать http post и http get без особых проблем). Вы можете хранить два поля: имя клиента и идентификатор клиента. Если имя клиента совпадает с именем в http get, вам не нужно извлекать идентификатор. Если они не совпадают, вы можете запросить в БД идентификатор. Идея состоит в том, чтобы кэшировать идентификатор, поэтому вы можете искать его по клиенту только один раз.

2 голосов
/ 21 октября 2011

Например, вы можете зашифровать id +, добавив к нему немного хеша.Таким образом, пользователь не может просто изменить его.

Или вы можете просто зашифровать свой id с помощью симметричного шифра, например AES или DES.Результат id будет длиннее (потому что они работают в блоках по 64-256 бит), и было бы невозможно изменить случайный символ и получить действительный id (технически с достаточным количеством попыток можно было бы сделать это).. Удачи!)

Пример кода

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

для id = 123 у нас есть закодированный id = 4E-CD-80-9E-7E-FB-A7-B9-74-B6-3A-37-57-9C-BD-A9.Я мог бы сделать его короче, используя Base64 или удалив -, но во втором случае код был бы немного сложнее.Без -: D2B4F51E6577967A2262E3AE51F3EC74, в Base64: 0rT1HmV3lnoiYuOuUfPsdA==

Учитывая ваше использование, вероятно, DES достаточно безопасен.С DES id будет:

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

. Чтобы использовать DES, измените все Aes на DES и удалите строки BlockSize и KeySize.

0 голосов
/ 21 октября 2011

Если вы хотите, чтобы результат был детерминированным, вы должны передать некоторую уникальную комбинацию параметров. В вашем случае вы могли бы использовать параметр «customername» с некоторым номером после него для клиентов с тем же именем (вы должны будете сохранить этот номер в вашей базе данных вместе с именем клиента). Например:

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

Ваша маска маршрута будет выглядеть примерно так: customer/{customername}_{customerIndex}/.

...