2011-10-21 75 views
5

我正在嘗試獲取友好的網址。此刻友好的URL是否有這樣的:傳遞身份證,但不顯示在實際的網址中

本地主機/客戶/ 1/namehere

我想他們是這樣的:

本地主機/客戶/ namehere

但仍然得到想要的ID(因爲我用這個ID搜索我的數據庫)。 我有什麼可能?這甚至有可能嗎?

這是我的圖路線:

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更改爲他們想要去的地方。而且不必擔心ID。 (但我仍然需要它:))

+0

如果我確實理解了你的問題 - 使用這種模式'localhost/customer/namehere',你唯一的問題是通過'ID'?如果是這樣,爲什麼不使用會話變量? –

回答

2

如果我正確理解你的問題,id是客戶端ID。

如果您不想顯示您的ID,則所有解決方案都不要使用數字ID,並直接按客戶端名稱進行查詢。 這確實有點慢,但並不慢。 您可以通過客戶端名稱獲得帶有「反向」查詢的id,您可以按客戶端名稱進行索引。

通過用戶名避免太多查詢的一種可能性是將ID存儲在會話中或隱藏字段中,使用post(您可以混合使用http post和http get而沒有太多問題)。 您可以存儲兩個字段:客戶端名稱和客戶端ID,如果客戶端名稱與http get中的名稱匹配,則不需要獲取該ID。如果他們不匹配,你可以查詢數據庫的ID。 這個想法是緩存id,所以你只能通過客戶端搜索id一次。

2

你可以例如加密id +添加一些散列。用這種方式用戶不能簡單地改變它。

或者您可以簡單地使用對稱密碼加密您的id,如AESDES。結果id會更長(因爲它們以64-256位的塊工作),並且不可能更改隨機字符並獲得有效的id(技術上足夠的嘗試可以做到這一點......祝你好運! )

A碼示例

// 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改變所有的AesDES並刪除BlockSizeKeySize線。

+0

哦,用戶是否改變它並不重要。我只是想讓它不顯示。這樣用戶就可以輕鬆地將url更改爲他們想要去的地方。 –

+0

@VincentvanderLinden如果想要保護只是爲了防止「改變」,那麼你只需要使用一些祕密鹽來散列它。那麼你的鏈接將是:123XXXXXXXX其中X是散列。然後,您可以檢查散列是否由您生成。如果你甚至想保護它免受「查看」(例如你不希望你的用戶知道有多少客戶),那麼你就加密+散列。或者你可以簡單地用(例如)ECC(橢圓曲線加密)對它進行加密。那麼輸出將會很長,並且隨機找到「正確的」輸出將是不可能的。 – xanatos

+0

@VincentvanderLinden假設你的鏈接是這個'localhost/customer/namehere?id = 1515870811'。你能猜出真實的ID嗎(不要用這麼愚蠢的算法 - 它是用1^0x5a5a5a5a生成的) –

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}/

相關問題