ASP.NET Web API'sini Kullanarak Oturuma Erişme


268

Oturumun ve REST'in el ele gitmediğinin farkındayım, ancak yeni Web API'sını kullanarak oturum durumuna erişmek mümkün değil mi? HttpContext.Current.Sessionher zaman sıfırdır.


4
[SessionState(SessionStateBehavior.Required)]üzerinde ApiControllerhile (veya yok .ReadOnlyolduğunda).
Roman Starkov

@RomanStarkov Bu işe yaramadı. Hangi ortamı kullanıyordunuz? .NET Core?
Bondolin

@Bondolin hayır, bu Core değildi.
Roman Starkov

@RomanStarkov MVC sonra? Onu bulmakta zorlanıyorum.
Bondolin

@Bondolin SessionStateAttribute ve evet, MVC.
Roman Starkov

Yanıtlar:


336

MVC

Bir MVC projesi için aşağıdaki değişiklikleri yapın (WebForms ve Dot Net Core aşağıdadır):

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);
    }

}

Bu çözüm, AJAX çağrıları yapmak için javascript'te temel URL'yi getirebileceğimiz ek bir bonusa sahiptir:

_Layout.cshtml

<body>
    @RenderBody()

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

    @RenderSection("scripts", required: false) 

ve sonra Javascript dosyalarımızda / kodumuzda oturuma erişebilen webapi çağrılarımızı yapabiliriz:

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

WebForms

Yukarıdakileri yapın ancak bunun yerine bir RouteCollection almak için WebApiConfig.Register işlevini değiştirin:

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

Ve sonra da Application_Start içinde aşağıdakileri çağırın:

WebApiConfig.Register(RouteTable.Routes);

Nokta Net Çekirdek

Microsoft.AspNetCore.Session NuGet paketini ekleyin ve aşağıdaki kod değişikliklerini yapın:

Startup.cs

ConfigureServices işlevi içindeki hizmetler nesnesinde AddDistributedMemoryCache ve AddSession yöntemlerini çağırın :

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

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

ve Yapılandır işlevinde UseSession'a bir çağrı ekleyin :

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

SessionController.cs

Denetleyicinize, en üste bir using ifadesi ekleyin:

using Microsoft.AspNetCore.Http;

ve sonra kodunuzda HttpContext.Session nesnesini aşağıdaki gibi kullanın:

    [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);
    }

şimdi vurabiliyor olmalısınız:

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

ve sonra bu URL’ye gitmek URL’yi çıkarır:

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

Dot net core içindeki oturum verilerine erişme hakkında daha fazla bilgi burada: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state

Performans Endişeleri

Simon Weaver'ın performansla ilgili aşağıdaki cevabını okuyun. Bir WebApi projesi içinde oturum verilerine erişiyorsanız, çok ciddi bir performans sonucu olabilir - ASP.NET'in eşzamanlı istekler için 200 ms gecikme uyguladığını gördüm. Bu, birçok eşzamanlı isteğiniz varsa toplanabilir ve felaket olabilir.


Güvenlik endişeleri

Kullanıcı başına kaynakları kilitlediğinizden emin olun; kimliği doğrulanmış bir kullanıcının WebApi'nizden erişimi olmayan verileri alamaması gerekir.

Microsoft'un ASP.NET Web API'sındaki Kimlik Doğrulama ve Yetkilendirme hakkındaki makalesini okuyun - https://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api

Microsoft'un Siteler Arası İstek Sahteciliği saldırılarını önleme hakkındaki makalesini okuyun. (Kısacası, AntiForgery.Validate yöntemine göz atın) - https://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks


7
Mükemmel. Basit ve işe yarıyor. MVC olmayanlar için, Global.ascx.cs dosyasına Application_PostAuthorizeRequest () öğesini eklemeniz yeterlidir.
mhenry1384

1
@JCallico teşekkürler, sanırım çoğu insan oturumu oluşturan ASP.NET sayfasına ilk vurdu.
Rocklan

3
Ayrıca yol WebApiConfig.UrlPrefix yanı sıra WebApiConfig.UrlPrefixRelative ile başlar nerede doğru dönmek için IsWebApiRequest () değiştirmek gerekiyordu. Bunun dışında beklendiği gibi çalışır.
gb2d

7
Bu düzeltme ile ilgili söylenecek bir şey var. SessionStateBehavior öğesini Gerekli olarak ayarlarken, webapi'nin darboğazını kaldırırsınız, çünkü tüm istekleriniz oturum nesnesindeki kilitler nedeniyle senkronize çalışır. Bunun yerine SessionStateBehavior.Readonly olarak çalıştırabilirsiniz. Bu şekilde oturum nesnesinde kilit oluşturmaz.
Michael Kire Hansen

2
Oturum durumu davranışını "Gerekli" olarak ayarlarken dikkatli olun. Yazma izinlerine sahip istekler oturumu kilitler ve istemci başına birden fazla HttpApplication oluşturulmasını önler. Oturum durumunu her rota için uygun bir seviyeye ayarlamanız gerekir. Lütfen cevabımı buraya bakın: stackoverflow.com/a/34727708/1412787
Axel Wilczek

66

Özel bir RouteHandler kullanarak oturum durumuna erişebilirsiniz.

// 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;
    }
}

Burada bulundu: http://techhasnoboundary.blogspot.com/2012/03/mvc-4-web-api-access-session.html


14
Güncelleme: API işlevleriniz oturumdan okursa ve oturumu değiştirmezse, IRequiresSessionState yerine IReadOnlySessionState kullanmak iyi bir fikir olabilir. Bu, API işlevinin işlenmesi sırasında oturumun kilitlenmemesini sağlar.
warrickh

6
MVC 4 - route.RouteHandler benim için çalışmıyor bile benim için bir özellik değil. @LachlanB benim için işe yaramış gibi görünüyor.
bkwdesign

3
MVC çözümüne işaret ettiğiniz için @bkwdesign'a teşekkürler. Bu yanıt yalnızca Web API'sı ile ilgilidir.
warrickh

2
Bu, Rota Özelliklerini desteklemiyor gibi görünüyor. Düşünceler?
Tim S

Bkwdesign'ın belirttiği gibi, bu artık desteklenmemektedir. Bununla birlikte, DataTokens kullanarak rota başına oturum durumu davranışını tanımlamanın bir yolu vardır: stackoverflow.com/a/34727708/1412787
Axel Wilczek

46

Session'ı WebAPI'de kullanmaktan neden kaçınmalısınız?

Performans, performans, performans!

Session'ı WebAPI'de hiç kullanmamanız için çok iyi ve genellikle gözden kaçan bir neden var.

Oturum kullanılırken ASP.NET'in çalışması, tek bir istemciden alınan tüm istekleri serileştirmektir . Şimdi nesne serileştirmesinden bahsetmiyorum - ancak bunları alınan sırayla çalıştırıyorum ve bir sonraki çalıştırmadan önce her birinin tamamlanmasını bekliyorum. Bu, iki istek aynı anda Oturum'a erişmeye çalışırsa, kötü iş parçacığı / yarış koşullarından kaçınmak içindir.

Eşzamanlı İstekler ve Oturum Durumu

ASP.NET oturum durumuna erişim oturum başına özeldir, yani iki farklı kullanıcı eşzamanlı istekte bulunursa, her ayrı oturuma aynı anda erişim izni verilir. Ancak, aynı oturum için (aynı SessionID değerini kullanarak) iki eşzamanlı istek yapılırsa, ilk istek oturum bilgilerine özel erişim elde eder. İkinci istek, yalnızca ilk istek tamamlandıktan sonra yürütülür.(İkinci istek, ilk istek kilit zaman aşımını aştığı için bilgilerdeki özel kilit serbest bırakıldığında da erişebilir.) @ Sayfa yönergesindeki EnableSessionState değeri ReadOnly olarak ayarlanmışsa, salt okunur isteği oturum bilgileri, oturum verilerinde özel bir kilit oluşturmaz. Ancak, oturum verileri için salt okunur isteklerin, oturum verilerinin temizlenmesi için bir okuma-yazma isteği tarafından ayarlanan bir kilidi beklemesi gerekebilir.

Peki bu Web API için ne anlama geliyor? Çok sayıda AJAX isteği çalıştıran bir uygulamanız varsa, o zaman bir seferde yalnızca BİR çalıştırılabilir. Daha yavaş bir isteğiniz varsa, bu istemciden diğer tüm işlemleri tamamlanıncaya kadar engeller. Bazı uygulamalarda bu çok belirgin bir şekilde durgun performansa neden olabilir.

Bu yüzden, kesinlikle kullanıcı oturumundan bir şeye ihtiyacınız varsa ve WebApi için etkinleştirmenin gereksiz performans cezasından kaçınmanız durumunda bir MVC denetleyicisi kullanmalısınız.

Thread.Sleep(5000)Bir WebAPI yöntemi koyarak ve oturumu etkinleştirerek bunu kendiniz kolayca test edebilirsiniz . 5 istek çalıştırın ve bu işlemlerin tamamlanması toplam 25 saniye sürecektir. Oturum olmadan toplam 5 saniyeden biraz fazla zaman alacaktır.

(Aynı mantık SignalR için de geçerlidir).


18
Yönteminiz yalnızca oturumdan okuyorsa, [SessionState (SessionStateBehavior.ReadOnly)] kullanarak bu sorunu çözebilirsiniz.
Rocklan

21

Haklısın, REST vatansız. Bir oturum kullanırsanız, işlem durum bilgisi olur, sonraki istekler durumu (oturumdan) kullanabilir.

Bir oturumun rehidre edilmesi için, durumu ilişkilendirmek için bir anahtar sağlamanız gerekir. Normal bir asp.net uygulamasında bu anahtar bir çerez (çerez oturumları) veya url parametresi (çerezsiz oturumlar) kullanılarak sağlanır.

Bir oturumu unutmanız gerekiyorsa, oturumlar REST tabanlı tasarımlarda önemsizdir. Doğrulama için bir oturuma ihtiyacınız varsa, bir jeton kullanın veya IP adreslerine göre yetkilendirin.


10
Bundan emin değilim. Microsoft örneklerinde Yetkilendirme özniteliğini kullanarak gösterirler. Bunu denedim ve Form Tabanlı Kimlik Doğrulama ile çalışır. Web API, varsayılan kimlik doğrulama çerezine iletilen kimlik doğrulama durumunun farkındadır.
Mark

4
Bahsettiğim örnek, code.msdn.microsoft.com/ASPNET-Web-API-JavaScript-d0d64dd7 . Yeni REST tabanlı Web API'sini kullanarak Form Kimlik Doğrulaması uygular.
Mark

4
Oturum durumuna gerek kalmadan [Yetkilendir] özelliğini başarıyla kullandım. Sadece kimliğini ayarlamak için bir kimlik doğrulama mesajı işleyicisi yazdım.
Antony Scott

57
Sorusuna bir yanıt sunmadığınız için sizi işaretlediniz ve dahası, Web Api, ajax ağır web uygulamasıyla harika çalışan asenkron bir çerçevedir. Kimse, Web API çerçevesini kullanmaktan yararlanmak için RESTful tasarımının tüm kiracılarına saygı duymanız gerektiğini söylemedi.
Brian Ogden

3
@MarkS. Web API'sının oturum durumunun farkında olmaması gerektiğini bildirme hakkı vardır. Olumsuz cevap hala bir cevap olmaya devam ediyor. Yukarı oy.
Antoine Meltzheim

20

Mark, nerddinner MVC örneğini kontrol ederseniz mantık hemen hemen aynıdır.

Çerezi almanız ve geçerli oturumda ayarlamanız yeterlidir.

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

Nerddinner projesinden ödünç alabileceğiniz "SampleIdentity" sınıfınızı tanımlamanız gerekir .


Kimlik sınıfı NerdDinner_2.0 \ NerdDinner \ Models \ NerdIdentity.cs dizinindedir.
mhenry1384

Bu benim için çalışmıyor (.NET 4'te). Asla o kurabiyem yok. Yalnızca FormsAuthentication açıksa çalışır mı?
mhenry1384

giriş formunu kullanarak kimlik doğrulaması yaptıktan sonra çerez gerçekten oluşturulur. Ayrıca nasıl / ne zaman oluşturulacağını özelleştirebilirsiniz, bkz. Stackoverflow.com/questions/7217105 Ancak yine de web sunucusuna karşı etkili bir şekilde kimlik doğrulaması yapmak için kullanıcıya ihtiyacınız var
JSancho

Soru HttpContext.Current.Session soruyor ve bu cevap ne yapılması gerektiğini net bir şekilde açıklamıyor. @LachlanB cevabına bakınız.
JCallico

14

Sorunu çözmek için:

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

Global.asax.cs içinde


4
Uyarı! Bu, TÜM istekler için oturumu etkinleştirir. Uygulamanız katıştırılmış kaynaklar kullanıyorsa bu gerçekten performansa zarar verebilir.
cgatian

@cgatian herhangi bir alternatif çözüm düzeltildi mi?
Kiquenet

@Treyphor'un önerdiği en iyi yaklaşım olduğunu düşünüyorum. Tüm istekler için etkinleştirmeyin. URL'de "/ api" veya başka bir şeye sahip yollar. Ayrıca, mümkünse oturum durumunu yalnızca API denetleyicileriniz için okuyacak şekilde ayarlayın.
cgatian

10

Sonuncusu şu anda çalışmıyor, bunu al, benim için çalıştı.

App_Start şirketinde WebApiConfig.cs

    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);
}

dördüncü burada: http://forums.asp.net/t/1773026.aspx/1


Bu en basit çözümdür, ancak aslında çalışmaz olması için kodda birkaç hata vardır. Buna dayanarak başka bir çözüm yayınladım, kendinizinkini eşleştirmek için kendiniz düzenlemekten çekinmeyin.
Rocklan

_WebApiExecutionPath satırındaki hafif düzeltmenin genel statik dizeyi okuması gerekir _WebApiExecutionPath = "~ / api";
stephen ebichondo

8

LachlanB'nin cevabından sonra, ApiController'ınız belirli bir dizinde (/ api gibi) oturmuyorsa, bunun yerine örneğin RouteTable.Routes.GetRouteData öğesini kullanarak isteği test edebilirsiniz:

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 de aynı sorunu vardı, ben tüm api denetleyicileri miras temel api denetleyicime bu yöntemi koyarak sabit:

    /// <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;
    }

Sonra api çağrınızda sadece oturuma erişmek istediğinizi yapın:

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

Ayrıca, diğer insanlar gibi Global.asax.cs dosyamda var, yukarıdaki yöntemi kullanarak yine de ihtiyacınız olup olmadığından emin değilim, ama burada sadece durum:

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

Ayrıca, oturuma ihtiyacınız olan api çağrılarınıza yapıştırabileceğiniz özel bir filtre niteliği de oluşturabilirsiniz, daha sonra normalde HttpContext.Current.Session ["SomeValue"] ile yaptığınız gibi api çağrınızda oturumu kullanabilirsiniz:

  /// <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;
        }
      }
    }
  }

Bu yardımcı olur umarım.


6

@LachlanB yaklaşımını izledim ve gerçekten de oturum çerezi istek üzerine mevcut olduğunda oturum kullanıma sunuldu. Eksik kısım Oturum çerezi istemciye ilk kez nasıl gönderilir?

Sadece HttpSessionState kullanılabilirliğini etkinleştirmekle kalmayıp aynı zamanda yeni bir oturum oluşturulduğunda çerezi istemciye gönderen bir HttpModule oluşturdum.

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);
    }
}

Harika çalışıyor. Bu, zaman aşımına uğramadığı sürece oturumu istekler arasında aynı tutar. Oturum durumunu gerekli ve sadece istek engellemeyi durdurmak için okumak arasında geçiş yapmak için iyi bir yol bulana kadar henüz kullanacağımdan emin değilim, ama bu bana arzu ettiğim başlangıç ​​yolunu verdi. Teşekkür ederim!
Derreck Dean

3

@LachlanB'nin cevabında bir şeyden bahsetmek gerekiyor.

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

Çizgiyi atlarsanız if (IsWebApiRequest())

Siteniz web form sayfalarıyla karıştırılmışsa, tüm sitenin sayfa yükleme yavaşlığı sorunu olacaktır.


0

Evet, oturum Rest API ile el ele gitmez ve bu uygulamalardan kaçınmalıyız. Ancak gereksinimlere göre, her istekte istemci sunucunun durum veya veri alışverişi yapabileceği veya koruyabileceği şekilde oturumu bir şekilde sürdürmemiz gerekir. Bu nedenle, REST protokollerini bozmadan bunu başarmanın en iyi yolu JWT gibi jetonla iletişim kurmaktır.

https://jwt.io/


-4

Temel bilgilere geri dönmek neden basit kalmasın ve Oturum değerini API'nıza aktarmak için gizli bir html değerinde saklamıyor?

kontrolör

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

$ (belge) .ready (function () {

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

    alert(sessionValue);

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

}


1
Eğer uygulama hem MVC hem de WebAPI kullanıyorsa Waht? Ayrıca, Sharepoint güvenlik belirteçleri gibi bazı şeylerin sunucu tarafında depolanması daha mantıklıdır. Azure blobs konteyneri gibi jeton depolaması için özel bir sargı uygulamak yerine, bazen bu tür veriler için makul bir şekilde yeniden kullanılabilir. Uygulama şablonunda uygulandığı şekliyle Sharepoint güvenlik bağlamı, oturumu bu güvenlik bağlamlarını depolamak için kullanır ve birkaç kilobayt veri yerine yalnızca küçük veri parçaları (oturum etiketi) aktarılır. Bu bağlam daha küçük olsaydı harika olurdu ...
Konstantin Isaev
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.