簡體   English   中英

如何使用asp.net MVC隱藏基於角色的部分在淘汰組件中

[英]How to hide role based section in knockout component using asp.net MVC

什么是阻止用戶在淘汰組件中看到管理員鏈接等內容的最佳方法?

如果用戶有權查看這些鏈接,我不想發出客戶端請求,因為它會在客戶端上公開此部分。

我能弄清楚的唯一方法是使用視圖來表示組件模板,然后在呈現HTML之前檢查用戶是否在服務器端是正確的。

但是,還有另一種比這更清潔的方式,還是正確的方法?

我在AngularJS Apps上面臨着類似的挑戰。

我喜歡在Model或ViewBag傳遞登錄狀態和角色,而不是執行額外的服務請求。

為簡單起見,我們假設我們正在使用ViewBag

1)Action Method中 ,設置

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 ,以檢查用戶是否具有正確的角色名稱:

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中查看:

3)綁定角色並登錄數據

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

隱藏管理組件的方法:

剃刀方式:

而不是使用Knockout隱藏組件,而是有C#/ Razor方式

- >嵌套if子句

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

...

}

Razor條件優於Knockout的優點是當服務器創建頁面時組件不會呈現,不會留下客戶端看到的痕跡

- > _Layout條件部分

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

比簡單的Razor Condition更清潔,並在整個應用程序中自動應用

- >部分與兒童行動

調用(Action, Controller, Parameter)

@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解決方案。

如果您無法將標記公開給客戶端,那么執行此操作的唯一方法是在生成標記之前在服務器上。 正如您所指出的,這將在視圖渲染中完成。

在您的情況下,使用部分視圖來保存您的KO組件是合適的,並提供您需要的功能,同時允許您重用組件標記。

這是我過去使用的方法,它非常干凈地工作:

視圖

<script type="text/javascript">
    ko.components.register("foo", {
        viewModel: FooComponentViewModel,
        template: { element: "component-foo" }
    });
</script>

...

<foo params="IsAdmin: @(User.IsInRole("Admin") ? 'true' : 'false')"></foo>

...

@Html.Partial("Components/_Foo")

如有必要,甚至可以通過MVC視圖模型將附加上下文傳遞給局部視圖。

組件部分視圖

<template id="component-foo">
    @if(@User.IsInRole("Admin"))
    {
        // something you DO care about the client seeing
    }

    ...
</template>

@if(@User.IsInRole("Admin"))
{
    <script type="text/javascript">
        // Some JS code to hide from non admins for this component
    </script>
}

組件視圖模型

function FooComponentViewModel(params) {
    var self = this;

    self.AdminDoSomething = function () {
        if (!params.IsAdmin) {
            return;
        }

        // something you DO NOT care about the client seeing...
    };
}

我知道在提供您所尋求的要求的同時,沒有更清潔的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM