Доступ до сесії за допомогою веб-API ASP.NET


268

Я усвідомлюю, що сеанс і REST точно не йдуть на руку, але чи не можна отримати доступ до стану сесії за допомогою нового веб-API? HttpContext.Current.Sessionзавжди недійсний.


4
[SessionState(SessionStateBehavior.Required)]на ApiControllerтрюк (або .ReadOnlyде це доречно).
Роман Старков

@RomanStarkov Не вдалося це зробити. Яке середовище ви використовували? .NET Core?
Бондолін

@Bondolin ні, це не було Core.
Роман Старков

@RomanStarkov MVC тоді? У мене виникають проблеми з її пошуку.
Бондолін

Відповіді:


336

MVC

Для проекту MVC внесіть такі зміни (відповідь WebForms та Dot Net Core нижче):

WebApiConfig.cs

public static class WebApiConfig
{
    public static string UrlPrefix         { get { return "api"; } }
    public static string UrlPrefixRelative { get { return "~/api"; } }

    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: WebApiConfig.UrlPrefix + "/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

Global.asax.cs

public class MvcApplication : System.Web.HttpApplication
{
    ...

    protected void Application_PostAuthorizeRequest()
    {
        if (IsWebApiRequest())
        {
            HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
        }
    }

    private bool IsWebApiRequest()
    {
        return HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.StartsWith(WebApiConfig.UrlPrefixRelative);
    }

}

Це рішення має додатковий бонус за те, що ми можемо отримати базову URL-адресу в JavaScript для здійснення дзвінків AJAX:

_Layout.cshtml

<body>
    @RenderBody()

    <script type="text/javascript">
        var apiBaseUrl = '@Url.Content(ProjectNameSpace.WebApiConfig.UrlPrefixRelative)';
    </script>

    @RenderSection("scripts", required: false) 

а потім у межах файлів / коду Javascript ми можемо робити наші дзвінки webapi, які можуть отримати доступ до сеансу:

$.getJSON(apiBaseUrl + '/MyApi')
   .done(function (data) {
       alert('session data received: ' + data.whatever);
   })
);

Веб-форми

Виконайте вище, але змініть функцію WebApiConfig.Register, щоб замість цього взяти RouteCollection:

public static void Register(RouteCollection routes)
{
    routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: WebApiConfig.UrlPrefix + "/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
}

А потім зателефонуйте в Application_Start:

WebApiConfig.Register(RouteTable.Routes);

Dot Net Core

Додайте пакет Microsoft.AspNetCore.Session NuGet і введіть такі зміни коду:

Startup.cs

Виклик методів AddDistributedMemoryCache та AddSession на об’єкті послуг в рамках функції ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    ...

    services.AddDistributedMemoryCache();
    services.AddSession();

і у функції Налаштування додайте виклик у UseSession :

public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
ILoggerFactory loggerFactory)
{
    app.UseSession();
    app.UseMvc();

SessionController.cs

У своєму контролері додайте використовувальний оператор вгорі:

using Microsoft.AspNetCore.Http;

а потім використовуйте об'єкт HttpContext.Session у коді так:

    [HttpGet("set/{data}")]
    public IActionResult setsession(string data)
    {
        HttpContext.Session.SetString("keyname", data);
        return Ok("session data set");
    }

    [HttpGet("get")]
    public IActionResult getsessiondata()
    {
        var sessionData = HttpContext.Session.GetString("keyname");
        return Ok(sessionData);
    }

тепер ви повинні мати можливість вдарити:

http://localhost:1234/api/session/set/thisissomedata

а потім перехід до цієї URL-адреси витягне його:

http://localhost:1234/api/session/get

Тут можна отримати більше інформації про доступ до даних сеансу в точці чистого ядра: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state

Побоювання щодо продуктивності

Прочитайте відповідь Саймона Вівер нижче щодо продуктивності. Якщо ви отримуєте доступ до даних сеансу всередині проекту WebApi, це може мати дуже серйозні наслідки для продуктивності - я бачив, як ASP.NET застосовує затримку в 200 мс для одночасних запитів. Це може скластись і стати згубним, якщо у вас буде багато одночасних запитів.


Проблеми безпеки

Переконайтеся, що ви блокуєте ресурси на кожного користувача - автентифікований користувач не повинен мати можливість отримувати дані з вашого WebApi, до яких вони не мають доступу.

Прочитайте статтю Microsoft про автентифікацію та авторизацію у веб-API ASP.NET - https://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api

Прочитайте статтю Майкрософт про уникнення хакерських атак між сайтом Request Forgery. (Коротше, ознайомтеся з методом AntiForgery.Validate) - https://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks


7
Ідеально. Просто і це працює. Для не-MVC просто додайте Application_PostAuthorizeRequest () до Global.ascx.cs.
mhenry1384

1
Дякую @JCallico, я думаю, що більшість людей першими потрапляють на сторінку ASP.NET, яка створює сеанс.
Роклан

3
Мені потрібно було змінити IsWebApiRequest (), щоб також повернути true там, де шлях починається з WebApiConfig.UrlPrefix, а також WebApiConfig.UrlPrefixRelative. Крім цього, працює як очікувалося.
gb2d

7
Щодо цього виправлення потрібно згадати. при встановленні SessionStateBehavior на Потрібне, ви обмежуєте роботу веб-сайтів, оскільки всі ваші запити будуть синхронізовані через блокування об’єкта сеансу. Ви можете замість цього запустити його як SessionStateBehavior.Readonly. Таким чином він не створюватиме блокування на об’єкт сеансу.
Майкл Кір Хансен

2
Будьте уважні, встановивши поведінку стану сеансу на "Обов'язково". Запити з дозволом на запис блокують сеанс і запобігають появі декількох HttpApplication на кожного клієнта. Ви повинні встановити стан сеансу на відповідному рівні для кожного маршруту. Будь ласка, зверніться до моєї відповіді тут: stackoverflow.com/a/34727708/1412787
Axel Wilczek

66

Ви можете отримати доступ до стану сеансу за допомогою спеціального RouteHandler.

// In global.asax
public class MvcApp : System.Web.HttpApplication
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        var route = routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        route.RouteHandler = new MyHttpControllerRouteHandler();
    }
}

// Create two new classes
public class MyHttpControllerHandler
    : HttpControllerHandler, IRequiresSessionState
{
    public MyHttpControllerHandler(RouteData routeData) : base(routeData)
    { }
}
public class MyHttpControllerRouteHandler : HttpControllerRouteHandler
{
    protected override IHttpHandler GetHttpHandler(
        RequestContext requestContext)
    {
        return new MyHttpControllerHandler(requestContext.RouteData);
    }
}

// Now Session is visible in your Web API
public class ValuesController : ApiController
{
    public string Get(string input)
    {
        var session = HttpContext.Current.Session;
        if (session != null)
        {
            if (session["Time"] == null)
                session["Time"] = DateTime.Now;
            return "Session Time: " + session["Time"] + input;
        }
        return "Session is not availabe" + input;
    }
}

Знайдено тут: http://techhasnoboundary.blogspot.com/2012/03/mvc-4-web-api-access-session.html


14
Оновлення: якщо ваші функції API читаються з сеансу і не змінюють сеанс, може бути корисною використовувати IReadOnlySessionState замість IRequiresSessionState. Це гарантує, що сеанс не буде заблокований під час обробки функції API.
warrickh

6
не працює для мене в MVC 4 - route.RouteHandler навіть не є власністю для мене. @LachlanB, здається, має те, що працювало на мене.
bkwdesign

3
Дякуємо @bkwdesign за вказівку на рішення MVC. Ця відповідь стосується лише веб-API.
warrickh

2
Схоже, це не підтримує атрибути маршруту. Думки?
Tim S

Як вказував bkwdesign, це більше не підтримується. Тим НЕ менше, існує спосіб визначення стану сеансу поведінки кожного маршруту з використанням DataTokens: stackoverflow.com/a/34727708/1412787
Axel Wilczek

46

Чому уникати використання сесії в WebAPI?

Продуктивність, продуктивність, продуктивність!

Є дуже хороша і часто недооцінена причина, чому ви взагалі не повинні використовувати сесію в WebAPI.

Те, як ASP.NET працює під час використання сесії - це серіалізація всіх запитів, отриманих від одного клієнта . Зараз я не говорю про серіалізацію об'єктів - але запускаю їх у отриманому порядку та чекаю, коли кожне завершиться перед запуском наступного. Це дозволяє уникнути неприємних умов потоку / гонки, якщо два запити намагаються отримати доступ до сесії одночасно.

Одночасні запити та стан сесії

Доступ до стану сеансу ASP.NET є виключним на сеанс, що означає, що якщо два різні користувачі роблять одночасні запити, доступ до кожного окремого сеансу надається одночасно. Однак якщо два одночасні запити зроблені для одного сеансу (використовуючи одне і те ж значення SessionID), перший запит отримує ексклюзивний доступ до інформації сеансу. Другий запит виконується лише після завершення першого запиту.(Другий сеанс також може отримати доступ, якщо ексклюзивний блокування інформації звільнено, оскільки перший запит перевищує тайм-аут блокування.) Якщо значення EnableSessionState в директиві @ Page встановлено на ReadOnly, запит на режим лише для читання інформація про сеанс не призводить до виключного блокування даних сеансу. Однак запити даних про сеанс лише для читання, можливо, доведеться чекати блокування, встановленого запитом читання-запису, щоб очистити дані сеансу.

То що це означає для веб-API? Якщо у вас є програма, що працює з багатьма запитами AJAX, тоді одночасно може працювати лише ONE. Якщо у вас є повільніший запит, він заблокує всіх інших від цього клієнта до його завершення. У деяких програмах це може призвести до дуже помітної швидкості роботи.

Тому, ймовірно, ви повинні використовувати контролер MVC, якщо вам абсолютно потрібне щось із сеансу роботи з користувачами, і уникати необхідного покарання ефективності включення його для WebApi.

Ви можете легко перевірити це на собі, просто Thread.Sleep(5000)ввівши метод WebAPI і включивши сеанс. Запустіть до нього 5 запитів, і на їх виконання знадобиться всього 25 секунд. Без сесії вони займуть загалом трохи більше 5 секунд.

(Це ж міркування стосується SignalR).


18
Ви можете обійти це за допомогою [SessionState (SessionStateBehavior.ReadOnly)], якщо ваш метод читається лише з сеансу.
Rocklan

21

Ну ви праві, REST без громадянства. Якщо ви використовуєте сеанс, обробка стане справжньою, наступні запити зможуть використовувати стан (з сеансу).

Для того, щоб сеанс був зволожений, вам потрібно надати ключ, щоб пов’язати стан. У звичайній програмі asp.net цей ключ надається за допомогою файлу cookie (cookie-сесії) або URL-адреси (без cookie сесій).

Якщо вам потрібен сеанс, забудьте відпочинок, сесії не мають значення в проектах на основі REST. Якщо вам потрібен сеанс для перевірки, тоді використовуйте маркер або авторизуйте IP-адреси.


10
Я не впевнений у цьому. У прикладах Microsoft вони показують за допомогою атрибута Authorize. Я спробував це, і це працює з використанням форми аутентифікації на основі форм. Web API знає стан аутентифікації, який передається у файлі cookie автентифікації за замовчуванням.
Марк

4
Ось зразок, на який я посилаюся , code.msdn.microsoft.com/ASPNET-Web-API-JavaScript-d0d64dd7 . Він використовує новий веб-API, заснований на REST, реалізує аутентифікацію форм.
Марк

4
Я успішно використовував атрибут [Авторизувати], не потребуючи стану сеансу. Я щойно написав обробник повідомлень про автентифікацію, щоб встановити особу.
Антоні Скотт

57
Відмітили вас, оскільки ви не запропонували відповіді на його проблему, і тим більше, що Web Api - це асинхронна основа, яка чудово працює з важким веб-додатком Ajax. Ніхто не сказав, що вам доведеться поважати всіх орендодавців RESTful дизайну, щоб отримати переваги від використання системи Web API.
Брайан Огден

3
@MarkS. правильно повідомити, що Web API не повинен знати про стан сеансу. Негативна відповідь як і раніше залишається відповіддю. Голосування вгору.
Антуан Мельцхайм

20

Зауважте , якщо ви перевірите приклад MVC nerddinner, логіка майже однакова.

Вам потрібно лише завантажити файл cookie та встановити його в поточному сеансі.

Global.asax.cs

public override void Init()
{
    this.AuthenticateRequest += new EventHandler(WebApiApplication_AuthenticateRequest);
    base.Init();
}

void WebApiApplication_AuthenticateRequest(object sender, EventArgs e)
{
    HttpCookie cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
    FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);

    SampleIdentity id = new SampleIdentity(ticket);
    GenericPrincipal prin = new GenericPrincipal(id, null); 

    HttpContext.Current.User = prin;
}

enter code here

Вам доведеться визначити свій клас "SampleIdentity", який ви можете позичити у проекту nerddinner .


Клас ідентичності знаходиться в NerdDinner_2.0 \ NerdDinner \ Models \ NerdIdentity.cs.
mhenry1384

Це не працює для мене (в .NET 4). Я ніколи цього печива не маю. Чи працює вона лише в тому випадку, якщо у вас увімкнено FormsAuthentication?
mhenry1384

файл cookie дійсно генерується після автентифікації через форму входу. Ви також можете налаштувати, як / коли це буде створено, дивіться stackoverflow.com/questions/7217105 Але користувачеві все ж потрібен для ефективної автентифікації проти веб-сервера
JSancho

Питання задає HttpContext.Current.Session, і ця відповідь чітко не пояснює, що потрібно зробити. Дивіться відповідь @LachlanB.
JCallico

14

Щоб вирішити проблему:

protected void Application_PostAuthorizeRequest()
{
    System.Web.HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
}

в Global.asax.cs


4
Увага! Це ввімкне сеанс для ВСІХ запитів. Це може дуже погіршити продуктивність, якщо ваша програма використовує вбудовані ресурси.
cgatian

@cgatian будь альтернативне рішення фіксованою ?
Кікенет

Я думаю, що найкращий підхід - це те, що пропонує @Treyphor. Не вмикайте його для всіх запитів. Просто маршрути, які мають "/ api" чи щось у URL-адресі. Також, якщо можливо, встановіть стан сеансу для читання лише для ваших контролерів API.
cgatian

10

Останній зараз не працює, візьміть цей, він працював на мене.

в WebApiConfig.cs на App_Start

    public static string _WebApiExecutionPath = "api";

    public static void Register(HttpConfiguration config)
    {
        var basicRouteTemplate = string.Format("{0}/{1}", _WebApiExecutionPath, "{controller}");

        // Controller Only
        // To handle routes like `/api/VTRouting`
        config.Routes.MapHttpRoute(
            name: "ControllerOnly",
            routeTemplate: basicRouteTemplate//"{0}/{controller}"
        );

        // Controller with ID
        // To handle routes like `/api/VTRouting/1`
        config.Routes.MapHttpRoute(
            name: "ControllerAndId",
            routeTemplate: string.Format ("{0}/{1}", basicRouteTemplate, "{id}"),
            defaults: null,
            constraints: new { id = @"^\d+$" } // Only integers 
        );

Global.asax

protected void Application_PostAuthorizeRequest()
{
  if (IsWebApiRequest())
  {
    HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
  }
}

private static bool IsWebApiRequest()
{
  return HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.StartsWith(_WebApiExecutionPath);
}

четверте тут: http://forums.asp.net/t/1773026.aspx/1


Це найпростіше рішення, але в коді є кілька помилок, так що він насправді не працює. Я опублікував ще одне рішення, засноване на цьому, сміливо редагуйте ваше, щоб відповідати моєму.
Rocklan

Невелика корекція у рядку _WebApiExecutionPath повинна читати загальнодоступний статичний рядок _WebApiExecutionPath = "~ / api";
Стівен Ебіхондо

8

Виходячи з відповіді LachlanB, якщо ваш ApiController не знаходиться в певній директорії (наприклад, / api), ви можете замість цього протестувати запит, використовуючи, наприклад, RouteTable.Routes.GetRouteData:

protected void Application_PostAuthorizeRequest()
    {
        // WebApi SessionState
        var routeData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(HttpContext.Current));
        if (routeData != null && routeData.RouteHandler is HttpControllerRouteHandler)
            HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
    }

8

У мене була така ж проблема в asp.net mvc, я її виправив, помістивши цей метод у свій базовий контролер api, який усі мої контролери api успадковують від:

    /// <summary>
    /// Get the session from HttpContext.Current, if that is null try to get it from the Request properties.
    /// </summary>
    /// <returns></returns>
    protected HttpContextWrapper GetHttpContextWrapper()
    {
      HttpContextWrapper httpContextWrapper = null;
      if (HttpContext.Current != null)
      {
        httpContextWrapper = new HttpContextWrapper(HttpContext.Current);
      }
      else if (Request.Properties.ContainsKey("MS_HttpContext"))
      {
        httpContextWrapper = (HttpContextWrapper)Request.Properties["MS_HttpContext"];
      }
      return httpContextWrapper;
    }

Потім у своєму дзвінку api, що ви хочете отримати доступ до сеансу, який ви просто робите:

HttpContextWrapper httpContextWrapper = GetHttpContextWrapper();
var someVariableFromSession = httpContextWrapper.Session["SomeSessionValue"];

У мене це також є у моєму файлі Global.asax.cs, як розмістили інші люди, не впевнений, чи потрібен він вам, використовуючи вищевказаний метод, але ось це на всякий випадок:

/// <summary>
/// The following method makes Session available.
/// </summary>
protected void Application_PostAuthorizeRequest()
{
  if (HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.StartsWith("~/api"))
  {
    HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
  }
}

Ви також можете просто створити спеціальний атрибут фільтра, який ви можете наклеїти на дзвінки api, які вам потрібні для сеансу, тоді ви можете використовувати сеанс у своєму api-дзвінку, як зазвичай, через HttpContext.Current.Session ["SomeValue"]:

  /// <summary>
  /// Filter that gets session context from request if HttpContext.Current is null.
  /// </summary>
  public class RequireSessionAttribute : ActionFilterAttribute
  {
    /// <summary>
    /// Runs before action
    /// </summary>
    /// <param name="actionContext"></param>
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
      if (HttpContext.Current == null)
      {
        if (actionContext.Request.Properties.ContainsKey("MS_HttpContext"))
        {
          HttpContext.Current = ((HttpContextWrapper)actionContext.Request.Properties["MS_HttpContext"]).ApplicationInstance.Context;
        }
      }
    }
  }

Сподіваюсь, це допомагає.


6

Я дотримувався @LachlanB підходу і дійсно сеанс був доступний, коли в запиті було присутнє печиво сеансу. Відсутня частина полягає в тому, як cookie Session надсилається клієнту вперше?

Я створив HttpModule, який не тільки забезпечує доступність HttpSessionState, але і надсилає cookie клієнту, коли створюється новий сеанс.

public class WebApiSessionModule : IHttpModule
{
    private static readonly string SessionStateCookieName = "ASP.NET_SessionId";

    public void Init(HttpApplication context)
    {
        context.PostAuthorizeRequest += this.OnPostAuthorizeRequest;
        context.PostRequestHandlerExecute += this.PostRequestHandlerExecute;
    }

    public void Dispose()
    {
    }

    protected virtual void OnPostAuthorizeRequest(object sender, EventArgs e)
    {
        HttpContext context = HttpContext.Current;

        if (this.IsWebApiRequest(context))
        {
            context.SetSessionStateBehavior(SessionStateBehavior.Required);
        }
    }

    protected virtual void PostRequestHandlerExecute(object sender, EventArgs e)
    {
        HttpContext context = HttpContext.Current;

        if (this.IsWebApiRequest(context))
        {
            this.AddSessionCookieToResponseIfNeeded(context);
        }
    }

    protected virtual void AddSessionCookieToResponseIfNeeded(HttpContext context)
    {
        HttpSessionState session = context.Session;

        if (session == null)
        {
            // session not available
            return;
        }

        if (!session.IsNewSession)
        {
            // it's safe to assume that the cookie was
            // received as part of the request so there is
            // no need to set it
            return;
        }

        string cookieName = GetSessionCookieName();
        HttpCookie cookie = context.Response.Cookies[cookieName];
        if (cookie == null || cookie.Value != session.SessionID)
        {
            context.Response.Cookies.Remove(cookieName);
            context.Response.Cookies.Add(new HttpCookie(cookieName, session.SessionID));
        }
    }

    protected virtual string GetSessionCookieName()
    {
        var sessionStateSection = (SessionStateSection)ConfigurationManager.GetSection("system.web/sessionState");

        return sessionStateSection != null && !string.IsNullOrWhiteSpace(sessionStateSection.CookieName) ? sessionStateSection.CookieName : SessionStateCookieName;
    }

    protected virtual bool IsWebApiRequest(HttpContext context)
    {
        string requestPath = context.Request.AppRelativeCurrentExecutionFilePath;

        if (requestPath == null)
        {
            return false;
        }

        return requestPath.StartsWith(WebApiConfig.UrlPrefixRelative, StringComparison.InvariantCultureIgnoreCase);
    }
}

Це чудово працює. Це зберігає сеанс однаковий між запитами, доки він не закінчився. Не впевнений, чи збираюся я використовувати його в prod лише поки я не знайду хороший спосіб переключити стан сеансу між необхідним і прочитаним лише для припинення блокування запиту, але це дало мені початковий шлях, який я бажаю. Дякую!
Деррек Дін

3

одне потрібно згадати у відповіді @LachlanB.

protected void Application_PostAuthorizeRequest()
    {
        if (IsWebApiRequest())
        {
            HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
        }
    }

Якщо опустити рядок if (IsWebApiRequest())

Весь сайт матиме проблему повільності завантаження сторінок, якщо ваш сайт змішаний зі сторінками веб-форм.


0

Так, сеанс не йде на руку з API відпочинку, а також ми повинні уникати цієї практики. Але відповідно до вимог нам потрібно підтримувати сеанс якось таким, щоб у кожному запиті сервер клієнта міг обмінюватися або підтримувати стан або дані. Отже, найкращий спосіб досягти цього, не порушуючи протоколи REST, - це комунікація через маркер, як JWT.

https://jwt.io/


-4

Повертаючись до основ, чому б не зробити це простим і зберегти значення Session у прихованому значенні html, щоб перейти до вашого API?

Контролер

public ActionResult Index()
        {

            Session["Blah"] = 609;

            YourObject yourObject = new YourObject();
            yourObject.SessionValue = int.Parse(Session["Blah"].ToString());

            return View(yourObject);
        }

cshtml

@model YourObject

@{
    var sessionValue = Model.SessionValue;
}

<input type="hidden" value="@sessionValue" id="hBlah" />

Javascript

$ (документ) .ready (функція () {

    var sessionValue = $('#hBlah').val();

    alert(sessionValue);

    /* Now call your API with the session variable */}

}


1
Що, якщо програма використовує як MVC, так і WebAPI? Крім того, більш доцільно деякі речі зберігати на стороні сервера, наприклад, маркери безпеки Sharepoint. Замість того, щоб застосовувати спеціальну обгортку для зберігання лексем, як-от контейнер з блакитними блошами, іноді доцільно повторно використовувати сеанс для цього типу даних. Контекст безпеки Sharepoint, реалізований у шаблоні додатків, використовує сеанс для зберігання цих контекстів безпеки та передається лише невеликі фрагменти даних (тег сеансу) замість кількох кілобайт даних. Було б дивовижно, якби цей контекст був меншим ...
Костянтин Ісаєв
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.