ASP. NET MVC Кэширование - зарегистрированный пользователь кэшируется - PullRequest
0 голосов
/ 17 января 2020

У меня есть ASP. NET MVC приложение, в котором я реализовал пользовательский фильтр кэширования, как показано ниже:

public class NonAuthenticatedOnlyCacheAttribute : OutputCacheAttribute
{
    public NonAuthenticatedOnlyCacheAttribute()
    {
        Duration = 600;  /*default cache time*/
    }

    private bool _partialView;
    public bool PartialView
    {
        get { return _partialView; }
        set
        {
            _partialView = value;
            if (_partialView)
            {
                VaryByCustom = "user";
            }
        }
    }

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        if (PartialView) OnCachePartialEnabled(filterContext);
        else OnCacheEnabled(filterContext);

        base.OnResultExecuting(filterContext);
    }

    private OutputCacheLocation? originalLocation;
    private int? _prevDuration;

    protected void OnCachePartialEnabled(ResultExecutingContext filterContext)
    {
        var httpContext = filterContext.HttpContext;

        if (!_prevDuration.HasValue) _prevDuration = Duration;
        Duration = httpContext.User.Identity.IsAuthenticated ? 1 : _prevDuration.Value;
    }

    protected void OnCacheEnabled(ResultExecutingContext filterContext)
    {
        var httpContext = filterContext.HttpContext;

        if (httpContext.User.Identity.IsAuthenticated)
        {
            // it's crucial not to cache Authenticated content
            originalLocation = originalLocation ?? Location;
            Location = OutputCacheLocation.None;
        }
        else
        {
            Location = originalLocation ?? Location;
        }

        // this smells a little but it works
        httpContext.Response.Cache.AddValidationCallback(IgnoreAuthenticated, null);
    }

    // This method is called each time when cached page is going to be
    // served and ensures that cache is ignored for authenticated users.
    private void IgnoreAuthenticated(HttpContext context, object data, ref HttpValidationStatus validationStatus)
    {
        validationStatus = context.User.Identity.IsAuthenticated
          ? HttpValidationStatus.IgnoreThisRequest
          : HttpValidationStatus.Valid;
    }
}

Проблема, с которой я сталкиваюсь, хотя Я не кэширую страницу для аутентифицированного пользователя, иногда я вижу кэшированную страницу какого-то другого аутентифицированного пользователя. Это случается редко и случайно.

Если я отлаживаю через это, он работает отлично, но не тогда, когда это происходит на сайте LIVE. Я также вижу, что в браузере также создается повар ie (".As pNet .ApplicationCook ie") аутентифицированного пользователя. (Означает ли это, что кэш вывода также кеширует и куки-файлы ответов?) Если я удаляю этот повар ie, то пользователь выходит из системы, что очевидно.

В Global.asax у меня есть следующий код:

public override string GetVaryByCustomString(HttpContext context, string value)
    {
        if (value.Equals("culture") || value.Equals("user"))
        {
            var customString = Thread.CurrentThread.CurrentUICulture.Name;
            if (context.User.Identity.IsAuthenticated)
            {
                customString = $"{context.User.Identity.Name}-{customString}";
            }
            return customString;
        }
        return base.GetVaryByCustomString(context, value);
    }

И на контроллере, ниже атрибут кэшируется

[NonAuthenticatedOnlyCacheAttribute(Location = System.Web.UI.OutputCacheLocation.Server, Duration = 600, VaryByCustom = "user")]

1 Ответ

0 голосов
/ 28 января 2020

Я думаю, что проблема может быть в том, что вы не сказали ASP. NET, что вы имеете в виду:

VaryByCustom = "user"

Возможно, вы это сделали, но код не включен в ваш пост. В вашем Global.asax.cs у вас будет что-то вроде:

public override string GetVaryByCustomString(HttpContext context, string arg) 
{ 
    if (arg.Equals("User", StringComparison.InvariantCultureIgnoreCase)) 
    {
        var user = context.User.Identity.Name; // TODO here you have to pick an unique identifier from the current user identity
        return string.Format("{0}@{1}", userIdentifier.Name, userIdentifier.Container); 
    }

    return base.GetVaryByCustomString(context, arg); 
}

Вы можете найти больше информации об этом здесь и здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...