ASP.NET 웹 API를 사용하여 세션에 액세스


268

세션과 REST가 정확히 일치하지는 않지만 새로운 웹 API를 사용하여 세션 상태에 액세스 할 수 없습니까? HttpContext.Current.Session항상 null입니다.


4
[SessionState(SessionStateBehavior.Required)]ApiController트릭 (또는 않는 .ReadOnly적절한을).
로마 Starkov

@RomanStarkov 작동시키지 못했습니다. 어떤 환경을 사용하고 있었습니까? .NET 코어?
Bondolin

@Bondolin 아니오, 이것은 핵심이 아닙니다.
Roman Starkov

그럼 @RomanStarkov MVC? 찾는 데 문제가 있습니다.
Bondolin

@Bondolin SessionStateAttribute 및 예, MVC.
로마 Starkov

답변:


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

}

이 솔루션에는 AJAX 호출을 위해 자바 스크립트에서 기본 URL을 가져올 수있는 추가 보너스가 있습니다.

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

WebForms

위의 작업을 수행하지만 대신 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);

닷넷 코어

Microsoft.AspNetCore.Session을 추가하십시오. NuGet 패키지를 후 다음 코드를 변경하십시오.

Startup.cs

ConfigureServices 함수 내의 서비스 오브젝트에서 AddDistributedMemoryCacheAddSession 메소드를 호출하십시오 .

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 문을 추가하십시오.

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에서 확인 하십시오.

성능 문제

성능에 관한 아래 Simon Weaver의 답변을 읽으십시오. WebApi 프로젝트 내에서 세션 데이터에 액세스하는 경우 성능에 심각한 결과를 초래할 수 있습니다. ASP.NET은 동시 요청에 대해 200ms 지연을 강제하는 것으로 나타났습니다. 동시 요청이 많을 경우 이로 인해 혼란이 발생할 수 있습니다.


보안 문제

인증 된 사용자는 WebApi에서 액세스 권한이없는 데이터를 검색 할 수 없어야합니다.

ASP.NET 웹 API의 인증 및 권한 부여에 대한 Microsoft의 기사를 읽으십시오-https: //www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api

Cross-Site Request Forgery 핵 공격 방지에 관한 Microsoft의 기사를 읽으십시오. (즉, 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 페이지를 먼저 방문하여 세션을 만듭니다.
Rocklan

3
WebApiConfig.UrlPrefixRelative뿐만 아니라 경로가 WebApiConfig.UrlPrefix로 시작하는 곳에서 true를 반환하도록 IsWebApiRequest ()를 수정해야했습니다. 그 외에는 예상대로 작동합니다.
gb2d

7
이 수정과 관련하여 언급 할 사항이 하나 있습니다. SessionStateBehavior를 Required로 설정하면 모든 요청이 세션 객체의 잠금으로 인해 동기화되어 실행되므로 webapi에 병목 현상이 발생합니다. 대신 SessionStateBehavior.Readonly로 실행할 수 있습니다. 이런 식으로 세션 개체에 대한 잠금을 만들지 않습니다.
Michael Kire Hansen

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 함수가 세션에서 읽고 세션을 수정하지 않으면 IRequiresSessionState 대신 IReadOnlySessionState를 사용하는 것이 좋습니다. 이를 통해 API 기능을 처리하는 동안 세션이 잠기지 않습니다.
warrickh 2016 년

6
MVC 4에서 나를 위해 작동하지 않습니다. @LachlanB가 나를 위해 일한 것 같습니다.
bkwdesign

3
MVC 솔루션을 지적한 @bkwdesign에게 감사합니다. 이 답변은 웹 API에만 해당됩니다.
warrickh

2
이것은 경로 속성을 지원하지 않는 것 같습니다. 생각?
Tim S

bkwdesign이 지적했듯이 더 이상 지원되지 않습니다. 그러나 DataTokens를 사용하여 경로 당 세션 상태 동작을 정의하는 방법은 무엇입니까 : stackoverflow.com/a/34727708/1412787
악셀 Wilczek

46

WebAPI에서 세션을 사용하지 않는 이유는 무엇입니까?

성능, 성능, 성능!

WebAPI에서 Session을 전혀 사용하지 않아야하는 매우 좋고 종종 간과 된 이유가 있습니다.

세션이 사용 중일 때 ASP.NET이 작동하는 방식 은 단일 클라이언트로부터받은 모든 요청직렬화하는 것 입니다. 이제 객체 직렬화에 대해 이야기하는 것이 아니라 수신 된 순서대로 실행하고 다음을 실행하기 전에 각각이 완료되기를 기다리는 것입니다. 이는 두 요청이 각각 세션에 동시에 액세스하려고 할 때 불쾌한 스레드 / 경쟁 조건을 피하기위한 것입니다.

동시 요청 및 세션 상태

ASP.NET 세션 상태에 대한 액세스는 세션마다 배타적이므로 두 명의 다른 사용자가 동시에 요청하면 각 개별 세션에 대한 액세스가 동시에 부여됩니다. 그러나 동일한 세션에 대해 동일한 SessionID 값을 사용하여 두 개의 동시 요청을하는 경우 첫 번째 요청은 세션 정보에 독점적으로 액세스합니다. 두 번째 요청은 첫 번째 요청이 완료된 후에 만 ​​실행됩니다.첫 번째 요청이 잠금 시간 종료를 초과하여 정보에 대한 독점 잠금이 해제되면 두 번째 세션도 액세스 할 수 있습니다. @ Page 지시문의 EnableSessionState 값이 ReadOnly로 설정되면 읽기 요청 -세션 정보만으로는 세션 데이터에 대한 독점 잠금이 발생하지 않습니다. 그러나 세션 데이터에 대한 읽기 전용 요청은 여전히 ​​세션 데이터에 대한 읽기 / 쓰기 요청에 의해 설정된 잠금이 지워질 때까지 기다려야 할 수 있습니다.

그렇다면 이것이 Web API의 의미는 무엇입니까? 많은 AJAX 요청을 실행하는 애플리케이션이있는 경우 한 번에 하나만 실행할 수 있습니다. 요청이 느리면 완료 될 때까지 해당 클라이언트의 다른 모든 요청을 차단합니다. 일부 응용 프로그램에서는 성능이 매우 느려질 수 있습니다.

따라서 사용자 세션에서 무언가가 절대적으로 필요하고 WebApi에 대해 불필요한 성능 저하를 피하려면 MVC 컨트롤러를 사용해야합니다.

Thread.Sleep(5000)WebAPI 메서드를 넣고 Session을 사용하면 쉽게 테스트 할 수 있습니다 . 요청을 5 개 실행하면 완료하는 데 총 25 초가 걸립니다. 세션이 없으면 총 5 초 이상 소요됩니다.

(동일한 추론이 SignalR에 적용됩니다).


18
메소드가 세션에서만 읽는 경우 [SessionState (SessionStateBehavior.ReadOnly)]를 사용하여이 문제를 해결할 수 있습니다.
Rocklan

21

REST는 상태 비 저장입니다. 세션을 사용하면 처리는 상태 저장 상태가되고 후속 요청은 세션의 상태를 사용할 수 있습니다.

세션을 재수 화하려면 상태를 연결하는 키를 제공해야합니다. 일반적인 asp.net 응용 프로그램에서 해당 키는 쿠키 (cookie-sessions) 또는 url 매개 변수 (cookieless sessions)를 사용하여 제공됩니다.

세션 잊어 버려 휴식이 필요한 경우 세션은 REST 기반 설계와 관련이 없습니다. 유효성 검사를 위해 세션이 필요한 경우 토큰을 사용하거나 IP 주소로 권한을 부여하십시오.


10
확실하지 않습니다. Microsoft의 예에서는 Authorize 속성을 사용하여 표시합니다. 나는 그것을 시도하고 양식 기반 인증과 함께 작동합니다. 웹 API는 기본 인증 쿠키에서 전달되는 인증 상태를 알고 있습니다.
Mark

4
다음은 내가 언급하는 샘플 code.msdn.microsoft.com/ASPNET-Web-API-JavaScript-d0d64dd7 입니다. 새로운 REST 기반 웹 API를 사용하여 양식 인증을 구현합니다.
Mark

4
세션 상태가 필요없이 [Authorize] 특성을 성공적으로 사용했습니다. 방금 ID를 설정하기 위해 인증 메시지 핸들러를 작성했습니다.
Antony Scott

57
그의 문제에 대한 답변을 제공하지 않았기 때문에 Web Api는 ajax Heavy Web App과 잘 작동하는 비동기 프레임 워크입니다. 웹 API 프레임 워크를 사용하여 이점을 얻으려면 RESTful 디자인의 모든 테넌트를 존중해야한다고 아무도 말하지 않았습니다.
Brian Ogden

3
@점수. Web API가 세션 상태를 인식하지 않아야한다는 것을 알 권리가 있습니다. 부정적인 대답은 여전히 ​​답입니다. 투표하십시오.
Antoine Meltzheim

20

Mark, nerddinner MVC 예제 를 확인 하면 논리가 거의 동일합니다.

쿠키를 검색하여 현재 세션에서만 설정하면됩니다.

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 프로젝트 에서 빌릴 수있는 "SampleIdentity"클래스를 정의해야합니다 .


ID 클래스는 NerdDinner_2.0 \ NerdDinner \ Models \ NerdIdentity.cs에 있습니다.
mhenry1384

이것은 나를 위해 작동하지 않습니다 (.NET 4에서). 나는 그 쿠키가 없다. FormsAuthentication을 설정 한 경우에만 작동합니까?
mhenry1384

로그인 양식을 통해 인증 한 후 쿠키가 실제로 생성됩니다. 생성 방법 / 시간을 사용자 정의 할 수도 있습니다. 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 대체 솔루션이 수정 되었습니까?
Kiquenet

가장 좋은 방법은 @Treyphor가 제안한 것입니다. 모든 요청에 ​​대해 활성화하지 마십시오. URL에 "/ api"등이있는 경로 만 있으면됩니다. 또한 가능하면 API 컨트롤러에 대해서만 세션 상태를 읽기 전용으로 설정하십시오.
cgatian

10

마지막 하나는 지금 작동하지 않습니다, 이것을 가지고, 그것은 나를 위해 일했습니다.

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

네 번째 : http://forums.asp.net/t/1773026.aspx/1


이것은 가장 간단한 솔루션이지만 실제로 작동하지 않도록 코드에 몇 가지 실수가 있습니다. 나는 이것을 기반으로 다른 솔루션을 게시했습니다. 내 것과 일치하도록 자유롭게 편집하십시오.
Rocklan

_WebApiExecutionPath 줄의 약간의 수정은 공개 정적 문자열을 읽어야합니다. _WebApiExecutionPath = "~ / api";
stephen ebichondo 11

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 호출을 고수 할 수있는 사용자 정의 필터 속성을 만들 수도 있습니다. 그런 다음 HttpContext.Current.Session [ "SomeValue"]를 통해 평소처럼 API 호출에서 세션을 사용할 수 있습니다.

  /// <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 접근 방식을 따르고 실제로 세션 쿠키가 요청에있을 때 세션을 사용할 수있었습니다. 누락 된 부분은 세션 쿠키가 클라이언트에 처음으로 전송되는 방법입니다.

HttpSessionState 가용성을 활성화 할뿐만 아니라 새 세션이 생성 될 때 쿠키를 클라이언트로 보내는 HttpModule을 만들었습니다.

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

이것은 잘 작동합니다. 시간이 초과되지 않는 한 요청간에 세션을 동일하게 유지합니다. 요청 차단을 중지하기 위해 세션 상태를 필수 및 읽기 전용으로 전환하는 좋은 방법을 찾을 때까지 아직 제품을 사용하지 않을지 확실하지 않지만 원하는 시작 경로를 제공합니다. 감사합니다!
Derreck Dean

3

@LachlanB의 답변에 대해 언급해야 할 것이 하나 있습니다.

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

줄을 생략하면 if (IsWebApiRequest())

사이트에 웹 양식 페이지가 혼합되어 있으면 전체 사이트에 페이지 로딩 속도 저하 문제가 발생합니다.


0

예, 세션은 Rest API와 밀접한 관련이 없으며 이러한 관행을 피해야합니다. 그러나 요구 사항에 따라 모든 요청에서 클라이언트 서버가 상태 또는 데이터를 교환하거나 유지할 수 있도록 세션을 유지해야합니다. 따라서 REST 프로토콜을 위반하지 않고이를 달성하는 가장 좋은 방법은 JWT와 같은 토큰을 통해 통신하는 것입니다.

https://jwt.io/


-4

기본으로 돌아가서 단순하게 유지하고 세션 값을 숨겨진 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" />

자바 스크립트

$ (document) .ready (function () {

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

    alert(sessionValue);

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

}


1
응용 프로그램이 MVC와 WebAPI를 모두 사용한다면? 또한 Sharepoint 보안 토큰과 같이 서버 측에 저장하는 것이 더 합리적입니다. Azure Blob 컨테이너와 같은 토큰 스토리지에 특수 래퍼를 구현하는 대신 때때로 이러한 유형의 데이터에 대해 합리적인 재사용 세션이 필요합니다. 앱 템플릿에서 구현 된 Sharepoint 보안 컨텍스트는 세션을 사용하여 이러한 보안 컨텍스트를 저장하며 몇 킬로바이트의 데이터 대신 전송되는 작은 데이터 조각 (세션 태그) 만 저장합니다. 이러한 상황이 더 작 으면 좋을 것입니다 ...
Konstantin Isaev
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.