传递ID,但不要在实际网址中显示

时间:2011-10-21 09:45:23

标签: c# asp.net-mvc asp.net-mvc-routing url-routing

我想获得友好的网址。目前友好的网址是这样的:

  

本地主机/客户/ 1 / namehere

我希望他们这样:

  

本地主机/客户/ namehere

但仍然需要id(因为我用这个id搜索我的数据库)。 我的可能性是什么?这甚至可能吗?

这是我的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)

感谢。

更新 哦,如果用户更改它并不重要。我只是想让它不显示。这样用户就可以轻松地将网址更改为他们想去的地方。而且不必担心ids。 (但我仍然需要它。:))

3 个答案:

答案 0 :(得分:2)

你可以加密id +加上一些哈希值。这样用户就不能简单地改变它。

或者您只需使用对称密码加密id,例如AESDES。结果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并删除BlockSizeKeySize行。

答案 1 :(得分:2)

如果我理解你的问题,那么id就是客户ID。

如果您不想显示您的ID,则解决方案是不使用数字ID并直接按客户端名称进行查询。 这确实有点慢但不是那么慢。 您可以通过客户端名称获取带有“反向”查询的ID,您可以按客户端名称进行索引。

通过用户名避免过多查询的一种可能性是使用post将id存储在会话中或表单中的隐藏字段中(您可以混合使用http post和http get而不会出现太多问题)。 您可以存储两个字段:客户端名称和客户端ID,如果客户端名称与http get中的名称匹配,则无需获取ID。如果它们不匹配,则可以在db中查询id。 我们的想法是缓存id,因此您只需按客户端搜索一次id。

答案 2 :(得分:0)

如果您希望结果具有确定性,则必须传递一些独特的参数组合。在您的情况下,对于具有相同名称的客户,您可以使用带有某个数字的“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}/