javascript - 如何使用 asp.net MVC 在挖空组件中隐藏基于角色的部分

标签 javascript asp.net asp.net-mvc razor knockout-3.0

防止用户在 knockout 组件中看到诸如管理链接之类的内容的最佳方法是什么?

如果用户有权查看这些链接,我不想发出客户端请求,因为这会在客户端上公开此部分。

我能弄清楚的唯一方法是使用 View 来表示组件模板,然后在呈现 HTML 之前检查用户是否在服务器端正确。

但是有没有比这更干净的另一种方法,或者这是正确的方法吗?

最佳答案

我在使用 AngularJS 应用时遇到过类似的挑战。

与其执行额外的服务请求,我更喜欢在 Model 或 ViewBag 中传递登录状态和 Angular 色。

为简单起见,假设我们使用的是 ViewBag

1)操作方法中,设置

ViewBag.loggedIn = User.Identity.IsAuthenticated;
ViewBag.userId = User.Identity.GetUserId();

var identity = (System.Security.Claims.ClaimsIdentity)User.Identity;
ViewBag.roles = identity.Claims
                .Where(c => c.Type == ClaimTypes.Role)
                .Select(c => c.Value);

2)JS 文件 中,全局定义UserModel 并使用绑定(bind)和函数来检查用户是否具有正确的 Angular 色名称:

var UserModel = function () {
    var self = this;
    self.isLoggedIn = ko.observable("");
    self.userId = ko.observable("");
    self.roles = ko.observableArray([]);


    // function to check if role passed is in array
    self.hasRole = function (roleName) {

      for (i = 0; 1 < self.roles.length ; i++ ) {
          if (self.roles[i] == roleName)
             return true
      }
      return false;
    }

};

var UserData = new UserModel();

在 .cshtml View 中:

3)绑定(bind) Angular 色和登录数据

<script type="text/javascript">
   UserData.isLoggedIn("@ViewBag.isLoggedIn");
   UserData.userId("@ViewBag.userId");
   UserData.roles(@Html.Raw(Json.Encode(ViewBag.roles));
</script>

4) 如果 Role 正确,则显示部分内容:

<div data-bind="visible: UserData.hasRole("Admin")>
          ....
</div>

隐藏管理组件的方法:

Razor 之道:

除了使用Knockout 隐藏组件,还有C#/Razor 方法

->嵌套if子句

@((List<String>) ViewBag.roles.contains("Admin")) 
{

...

}

Razor Conditions 相对于 Knockout 的优势是组件不会在服务器创建页面时呈现,不会留下客户端可见的痕迹

-> _Layout 中的条件部分

@if ((List<String>) ViewBag.roles.contains("Admin"))
{
    @RenderSection("Admin Section")
}

比简单的 Razor Condition 更干净,并在整个应用程序中自动应用

->部分带有子 Action

调用( Action , Controller ,参数):

@Html.Action("AdminConsole", "Admin", new { Role = "Admin"})

public ActionResult AdminComponent(string Role)
        {

            If (List<String>) ViewBag.roles.contains("Admin")
                  return PartialView(
            return View(products);
        }

所有方法中最干净的。可以组合成一个部分以提供更大的便利。


关于如何隐藏管理组件的结论:

您选择如何隐藏管理组件取决于您的需要。 Razor/C# 方法更方便,也更安全。

另一方面,如果您有兴趣为用户提供 SPA 体验,C# 和服务器方法就达不到要求。您是否允许用户在不刷新页面的情况下进行身份验证?如果是这样,管理员可以进行身份​​验证并将匿名用户更改为管理员。

如果您愿意刷新屏幕以显示更改的内容,C#/Razor 是您的方法。如果您的首要任务是为用户提供“响应式体验”,您将希望实现Knockout 解决方案。

关于javascript - 如何使用 asp.net MVC 在挖空组件中隐藏基于角色的部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30788235/

相关文章:

asp.net - EF5 Code First ALTER TABLE 语句与 FOREIGN KEY 约束冲突

asp.net - 如何在 ASP.NET Core 中进行这样的文件上传?

c# - ASP.Net MVC Update ViewModel on DropDown Selection changed

javascript - 无法删除 useEffect 之外的事件监听器

javascript - 如何使用 JavaScript SDK 将位置信息发布到 Facebook

c# - 重构ViewModel映射-处理多个服务调用

c# - 在 api Controller 初始化之前设置参数

javascript - 在我的 React 应用程序中出现解析错误

javascript - 引导上下文类之间的淡化过渡

javascript - 如何为 farbtastic 设置初始颜色?