缓存MVC操作的输出,但是只对经过身份验证的用户使用缓存的版本。

时间:2023-01-21 15:38:01

I'd like to cache the output of my MVC actions. However:

我想缓存MVC动作的输出。然而:

1) If I apply the OutputCacheAttribute globally, it is risky as it caches everything for all users.

1)如果我全局地应用OutputCacheAttribute,这是有风险的,因为它缓存所有的用户。

2) If I apply OutputCacheAttribute globally and then apply the Authorize attribute on those actions that require authorization, that still does not solve the problem. All output is still cached regardless of the user having been authorized or not.

2)如果我全局应用OutputCacheAttribute,然后对那些需要授权的操作应用Authorize属性,这仍然不能解决问题。无论用户是否被授权,所有输出仍然被缓存。

3) If I apply the OutputCacheAttribute (not globally but) only on select actions, and have the AuthorizeAttribute on all actions that require authorization, then there is no security threat but there is a performance cost. Every page that requires authentication will need to make a fresh Http request.

3)如果我只在select操作上应用OutputCacheAttribute(不是全局的),并且在所有需要授权的操作上都有AuthorizeAttribute,那么就没有安全威胁,但是会有性能代价。需要身份验证的每个页面都需要发出一个新的Http请求。

I want to find a middle-ground so that selected pages, and/or selected types of requests (HTTP GET) are cached at the client but only if the user is authenticated. If the user logs out and accesses the url of the cached page/action, he must not be able to see the content.

我希望找到一个中间地带,以便在客户端缓存所选的页面和/或所选的请求类型(HTTP GET),但前提是用户经过身份验证。如果用户登出并访问缓存页面/操作的url,则必须不能看到内容。

Is there a way to implement this?

有办法实现这一点吗?

1 个解决方案

#1


2  

VaryByCustom is what you want. Put this in your Global.asax file:

你想要的就是变化无常。把这个放到全局中。asax文件:

public override string GetVaryByCustomString(HttpContext context, string custom)
{
    // use this algorithm to determine cacheability for "IsAuthenticated"
    if ("IsAuthenticated".Equals(custom, StringComparison.OrdinalIgnoreCase))
    {
        // cache content when user is authenticated
        if (User.Identity.IsAuthenticated) return "true";

        // do not cache when user is not authenticated
        return null;
    }

    return base.GetVaryByCustomString(context, custom);
}

... then use something like this on an action method you want to cache:

…然后在您想要缓存的操作方法上使用类似的东西:

[OutputCache(VaryByCustom = "IsAuthenticated", Duration = 1800,
    Location = OutputCacheLocation.Client)]
public virtual ActionResult Index()
{ ... }

#1


2  

VaryByCustom is what you want. Put this in your Global.asax file:

你想要的就是变化无常。把这个放到全局中。asax文件:

public override string GetVaryByCustomString(HttpContext context, string custom)
{
    // use this algorithm to determine cacheability for "IsAuthenticated"
    if ("IsAuthenticated".Equals(custom, StringComparison.OrdinalIgnoreCase))
    {
        // cache content when user is authenticated
        if (User.Identity.IsAuthenticated) return "true";

        // do not cache when user is not authenticated
        return null;
    }

    return base.GetVaryByCustomString(context, custom);
}

... then use something like this on an action method you want to cache:

…然后在您想要缓存的操作方法上使用类似的东西:

[OutputCache(VaryByCustom = "IsAuthenticated", Duration = 1800,
    Location = OutputCacheLocation.Client)]
public virtual ActionResult Index()
{ ... }