Zdaję sobie sprawę, że sesja i REST nie idą w parze, ale czy nie można uzyskać dostępu do stanu sesji przy użyciu nowego interfejsu API sieci Web? HttpContext.Current.Session
jest zawsze zerowy.
asp.net
asp.net-web-api
znak
źródło
źródło
[SessionState(SessionStateBehavior.Required)]
naApiController
lewę (lub w.ReadOnly
razie potrzeby).Odpowiedzi:
W przypadku projektu MVC wprowadź następujące zmiany (poniżej znajdują się odpowiedzi na formularze WebForms i Dot Net Core):
WebApiConfig.cs
Global.asax.cs
To rozwiązanie ma dodatkową zaletę, że możemy pobrać podstawowy adres URL w javascript do wykonywania wywołań AJAX:
_Layout.cshtml
a następnie w plikach / kodzie JavaScript możemy wykonywać nasze wywołania webapi, które mogą uzyskać dostęp do sesji:
Wykonaj powyższe czynności, ale zmień funkcję WebApiConfig.Register, aby zamiast tego pobrać RouteCollection:
A następnie wywołaj następujące w Application_Start:
Dodaj pakiet NuGet Microsoft.AspNetCore.Session , a następnie wprowadź następujące zmiany kodu:
Startup.cs
Wywołaj metody AddDistributMemoryCache i AddSession w obiekcie usług w ramach funkcji ConfigureServices:
i w funkcji Konfiguruj dodaj wywołanie do UseSession :
SessionController.cs
W swoim kontrolerze dodaj instrukcję using u góry:
a następnie użyj obiektu HttpContext.Session w kodzie w następujący sposób:
powinieneś teraz być w stanie trafić:
a następnie przejście do tego adresu URL spowoduje jego wyciągnięcie:
Więcej informacji na temat uzyskiwania dostępu do danych sesji w ramach dot net core tutaj: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state
Przeczytaj poniżej odpowiedź Simona Weavera dotyczącą wydajności. Jeśli uzyskujesz dostęp do danych sesji w projekcie WebApi, może to mieć bardzo poważny wpływ na wydajność - widziałem, jak ASP.NET wymusza opóźnienie 200 ms dla równoczesnych żądań. Może się to sumować i stać się katastrofalne, jeśli masz wiele równoczesnych żądań.
Upewnij się, że blokujesz zasoby na użytkownika - uwierzytelniony użytkownik nie powinien mieć możliwości pobierania danych z WebApi, do których nie ma dostępu.
Przeczytaj artykuł Microsoftu na temat uwierzytelniania i autoryzacji w ASP.NET Web API - https://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api
Przeczytaj artykuł Microsoftu na temat unikania ataków hakerskich na żądanie krzyżowej witryny. (W skrócie, sprawdź metodę AntiForgery.Validate) - https://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks
źródło
Dostęp do stanu sesji można uzyskać za pomocą niestandardowego narzędzia RouteHandler.
Znalezione tutaj: http://techhasnoboundary.blogspot.com/2012/03/mvc-4-web-api-access-session.html
źródło
Dlaczego warto unikać używania sesji w WebAPI?
Wydajność, wydajność, wydajność!
Jest bardzo dobry i często pomijany powód, dla którego nie powinieneś w ogóle używać Sesji w WebAPI.
Sposób działania ASP.NET podczas korzystania z sesji polega na serializacji wszystkich żądań otrzymanych od jednego klienta . Teraz nie mówię o serializacji obiektów, ale uruchamiam je w otrzymanej kolejności i czekam na zakończenie każdego z nich przed uruchomieniem następnego. Ma to na celu uniknięcie nieprzyjemnych warunków dotyczących wątku / wyścigu, jeśli dwa żądania próbują uzyskać dostęp do sesji jednocześnie.
Co to oznacza dla Web API? Jeśli masz aplikację obsługującą wiele żądań AJAX, tylko JEDNA będzie mogła być uruchomiona jednocześnie. Jeśli masz wolniejsze żądanie, spowoduje to zablokowanie wszystkich pozostałych klientów tego klienta, dopóki nie zostanie zrealizowane. W niektórych aplikacjach może to prowadzić do bardzo zauważalnie niskiej wydajności.
Dlatego prawdopodobnie powinieneś użyć kontrolera MVC, jeśli absolutnie potrzebujesz czegoś z sesji użytkownika i uniknąć niepotrzebnej utraty wydajności w przypadku włączenia go dla WebApi.
Możesz to łatwo sprawdzić sam, wprowadzając
Thread.Sleep(5000)
metodę WebAPI i włączając sesję. Wykonaj do niego 5 próśb, a ich wypełnienie zajmie 25 sekund. Bez sesji zajmie to nieco ponad 5 sekund.(To samo rozumowanie dotyczy SignalR).
źródło
Masz rację, REST jest bezpaństwowcem. Jeśli użyjesz sesji, przetwarzanie stanie się stanowe, kolejne żądania będą mogły użyć stanu (z sesji).
Aby sesja została uwodniona, musisz podać klucz do powiązania stanu. W normalnej aplikacji asp.net klucz ten jest dostarczany za pomocą pliku cookie (sesje cookie) lub parametru adresu URL (sesje bez plików cookie).
Jeśli potrzebujesz sesji zapomnij o odpoczynku, sesje nie mają znaczenia w projektach opartych na REST. Jeśli potrzebujesz sesji do weryfikacji, użyj tokena lub autoryzuj według adresów IP.
źródło
Zaznacz, jeśli sprawdzisz przykład MVC nerddinner, logika jest prawie taka sama.
Wystarczy pobrać plik cookie i ustawić go w bieżącej sesji.
Global.asax.cs
Musisz zdefiniować klasę „SampleIdentity”, którą możesz pożyczyć z projektu nerddinner .
źródło
Aby rozwiązać problem:
w Global.asax.cs
źródło
Ostatni nie działa teraz, weź ten, działał dla mnie.
w WebApiConfig.cs w App_Start
Global.asax
po czwarte tutaj: http://forums.asp.net/t/1773026.aspx/1
źródło
Zgodnie z odpowiedzią LachlanB, jeśli Twój ApiController nie znajduje się w określonym katalogu (jak / api), możesz zamiast tego przetestować żądanie za pomocą RouteTable.Routes.GetRouteData, na przykład:
źródło
Miałem ten sam problem w asp.net mvc, naprawiłem go, umieszczając tę metodę w moim podstawowym kontrolerze interfejsu API, który dziedziczą wszystkie moje kontrolery interfejsu API:
Następnie w interfejsie API, który chcesz uzyskać dostęp do sesji, po prostu wykonaj:
Mam to również w moim pliku Global.asax.cs, tak jak inne osoby, nie jestem pewien, czy nadal potrzebujesz go za pomocą powyższej metody, ale tutaj jest tak na wszelki wypadek:
Możesz także utworzyć niestandardowy atrybut filtru, który możesz trzymać na wywołaniach interfejsu API potrzebnych do sesji, a następnie możesz użyć sesji w wywołaniu interfejsu API, tak jak zwykle za pośrednictwem HttpContext.Current.Session [„SomeValue”]:
Mam nadzieję że to pomoże.
źródło
Postępowałem zgodnie z podejściem @LachlanB i rzeczywiście sesja była dostępna, gdy plik cookie sesji był obecny na żądanie. Brakuje tego, w jaki sposób plik cookie sesji jest wysyłany do klienta po raz pierwszy?
Utworzyłem HttpModule, który nie tylko włącza dostępność HttpSessionState, ale także wysyła ciasteczko do klienta, gdy tworzona jest nowa sesja.
źródło
jedną rzecz należy wspomnieć w odpowiedzi @LachlanB.
Jeśli pominiesz linię
if (IsWebApiRequest())
W całej witrynie występuje problem spowolnienia ładowania strony, jeśli jest ona pomieszana ze stronami formularzy internetowych.
źródło
Tak, sesja nie idzie w parze z Rest API, a także powinniśmy unikać tych praktyk. Ale zgodnie z wymaganiami musimy w jakiś sposób utrzymywać sesję, aby na każde żądanie serwer klienta mógł wymieniać lub utrzymywać stan lub dane. Tak więc najlepszym sposobem na osiągnięcie tego bez złamania protokołów REST jest komunikacja za pomocą tokena, takiego jak JWT.
https://jwt.io/
źródło
Wracając do podstaw, dlaczego nie uprościć tego i zapisać wartość sesji w ukrytej wartości HTML, aby przekazać ją do interfejsu API?
Kontroler
cshtml
JavaScript
$ (dokument) .ready (function () {
}
źródło