如何用asp.net MVC4隐藏URL中的ID

时间:2015-08-14 08:19:39

标签: asp.net asp.net-mvc-4

我的网址

  

http://www.domain.com/Products/ {别名} - {ID}

和我的路线

routes.MapRoute(
               name: "ProductDetail",
               url: "Products/{Alias}-{detailId}",
               defaults: new { controller = "Products", action = "ProductDetail", id = UrlParameter.Optional }
            );

在控制器中

public ActionResult ProductDetail(int? detailId)
        {
            var pro = db.Products.Find(detailId);
            if (pro == null)
            {
                return RedirectToAction("Index", "NotFound");
            }
            return View(pro);
        }

现在,我想在我的网址中隐藏ID,如

  

http://www.domain.com/Products/ {别名}

我该怎么做

1 个答案:

答案 0 :(得分:8)

简答

不可能做你想做的事。如果您希望能够从控制器访问detailId,则必须将detailId作为网址的一部分传递 - 您无法访问不存在的内容。

长答案

还有其他方法可以让用户“隐藏”detailId,这里有一些建议:

<强> 1。请改用Alias:

您可以同时删除detailId并改为使用Alias值。但是,这需要Alias值对您要查询的产品是唯一的,并且所需的更改可能如下所示:

routes.MapRoute(
    //..
    url: "Products/{Alias}",
    //..
);

public ActionResult ProductDetail(string Alias)
{
    var pro = db.Products.FindByAlias(Alias);
    //...
}

<强> 2。使用POST请求:

另一个有效隐藏URL detailId但仍然允许将值传递给控制器​​的解决方案是使用POST请求,其中参数值将在POST请求体中指定。

然而,缺点是您不能简单地为用户提供点击的URL,并且您网站中的编码链接需要花费更多的精力。通常使用MVC,POST请求在提交表单时发生,您也可以使用javascript ajax调用执行POST请求。

在这个答案中有点太多了,所以如果你有兴趣那么做一些研究,比如this question,或者一些info here

第3。加密detailId值:

现在这个选项不会隐藏URL中的detailId,但是如果您担心的是当前ID太用户友好,那么您可以'加密'(松散地使用)该值。例如,您可以转换为base64字符串,然后返回到控制器中的int。这会给你一个像这样的URL:

http://www.domain.com/Products/{Alias}-MQ%3D%3D

此网址将1表示为detailId,如果使用此方法,您必须确保URL encode/decode您的值。

在这种情况下,Base64转换并不是真正“加密”它,任何半精明的用户都会注意到这一点,并且可以绕过它。但是,如果您想采用这种方法,只有服务器知道加密/解密密钥,您就可以轻松使用更安全的双向加密算法。这里的缺点是只有服务器才能为用户生成有效的URL以“点击”。

此时值得考虑的是,如果您担心的是,通过包含简单的数字ID,URL太用户友好,那么问题是:您为什么关心?

如果您担心用户可以简单地更改detailId值,然后可以访问他们应该有权访问的产品,那么您的安全问题会更严重。如果是这种情况,那么您的控制器应负责任地验证用户是否可以访问他们尝试访问的产品,然后采取相应措施。

所有安全检查和验证都应该在服务器端处理,永远不要依赖客户端代码或用户操作来为您完成。