Dangers of using IHttpContextAccessor
Summary
TLDRВ этом видео Антон рассматривает проблемы, связанные с использованием IH HTTP Context Accessor в ASP.NET Core. Он объясняет, как и когда возникают эти проблемы, и как их избежать. Антон также рассматривает внутреннюю работу HTTP-контекста и дает советы, как стать лучшим инженером, имея лучшее понимание инструментов, которыми вы пользуетесь. Он также предлагает курсы по программированию на C# и приглашает заинтересованных вступить в его сервер Discord.
Takeaways
- 😀 В видео обсуждается проблема использования IH HTTP Context Accessor и как избежать таких проблем.
- 🛠 Рассматривается техническая сторона работы HTTP Context и того, как он появляется в приложении.
- 🔍 Авторы стремятся повысить осведомленность инженеров о средствах, которыми они пользуются, предоставляя примеры и объяснения.
- 💻 В видео представлены примеры кода, демонстрирующие, как может возникнуть проблема с HTTP Context Accessor.
- 🔗 Обсуждается важность понимания того, что бизнес-логика должна существовать вне ASP.NET Core сервера.
- 📚 Рассказывается о том, что бизнес-логика, внедряемая через контейнер внедрения зависимостей, не должна зависеть от сервисов, построенных для ASP.NET Core.
- 🚫 Подчеркивается, что использование IHttpContextAccessor для доступа к пользователю или другому состоянию из HTTP-запроса может привести к ошибкам.
- 🔄 Объясняется, что HTTP Context создается при начале запроса и уничтожается при его завершении, что может вызвать проблемы, если не учесть этот момент.
- 🧩 Авторы дают советы о том, как правильно извлекать информацию из HTTP-запроса перед тем, как она будет передана в бизнес-логику.
- 🎓 В заключении подчеркивается, что бизнес-логика должна быть разработана так, чтобы она не знала о существовании веб-сервера, чтобы избежать подобных проблем.
Q & A
Что такое IH HTTP Context Accessor и в чем его проблема?
-IH HTTP Context Accessor - это сервис, который предоставляет доступ к контексту HTTP-запроса в ASP.NET Core. Проблема заключается в том, что он может быть неопределенным или иметь значение null, когда попытка доступа к нему происходит вне области запроса, что может привести к ошибкам.
Какие проблемы могут возникнуть при использовании IH HTTP Context Accessor?
-Проблемы могут включать в себя исключения, связанные с доступом к null-контексту, а также проблемы с асинхронными или фоновыми операциями, которые пытаются получить доступ к информации из HTTP-контекста после завершения запроса.
Какое поведение демонстрирует пример с сервисом, который вызывает исключение?
-В примере с сервисом, который вызывает исключение, функция 'somethingSlowlySync' запускает фоновую задачу, пытается получить доступ к HTTP-контексту для уведомления пользователя, но в результате получает исключение из-за отсутствия контекста.
Что означает термин 'async local' в контексте IH HTTP Context Accessor?
-'Async local' - это механизм, который позволяет сохранять локальную информацию для текущего асинхронного потока выполнения. В случае с IH HTTP Context Accessor, 'async local' используется для хранения информации о HTTP-контексте для текущего запроса.
Какое влияние оказывает использование IH HTTP Context Accessor на архитектуру приложения?
-Использование IH HTTP Context Accessor может привести к плохим практикам, когда бизнес-логика приложения становится зависимой от контекста HTTP, что может сделать код менее гибким и трудным для тестирования и повторного использования.
Как можно избежать проблем с IH HTTP Context Accessor?
-Чтобы избежать проблем, необходимо извлекать все необходимые данные из HTTP-контекста на этапе входа в приложение и передавать их в бизнес-логику, а также избегать прямого доступа к IH HTTP Context Accessor в асинхронных или фоновых задачах.
Чем отличается использование IH HTTP Context Accessor в контроллерах MVC от использования в фоновых сервисах?
-В контроллерах MVC доступ к IH HTTP Context Accessor осуществляется в контексте HTTP-запроса, и контекст доступен и актуален. В фоновых сервисах же контекст может быть недоступен или уже уничтожен, что приводит к проблемам.
Каковы ключевые моменты, которые нужно понимать для избегания ошибок с использованием IH HTTP Context Accessor?
-Ключевые моменты включают понимание жизненного цикла HTTP-сервера, отделение бизнес-логики от серверной инфраструктуры, и извлечение и передача данных из HTTP-контекста в бизнес-логику перед началом обработки запроса.
Какие рекомендации Антон дает для работы с HTTP-контекстом в ASP.NET Core?
-Антон рекомендует изучить концепцию HTTP-сервера, разработать бизнес-логику, которая может существовать вне ASP.NET Core, и избегать использования сервисов, построенных для ASP.NET Core, в бизнес-логике.
Что такое 'Default HTTP Context Factory' и как он связан с IH HTTP Context Accessor?
-'Default HTTP Context Factory' - это сервис, который отвечает за создание и инициализацию HTTP-контекста для каждого запроса. Он связан с IH HTTP Context Accessor тем, что через него устанавливается связь между созданным HTTP-контекстом и доступом к нему через accessor.
Outlines
😀 Вступление и проблема с контекстом HTTP
Антон приветствует зрителей на своем YouTube-канале и объявляет, что сегодня будет обсуждаться проблема, связанная с доступом к контексту HTTP в ASP.NET Core. Он планирует рассмотреть, какие проблемы могут возникнуть при работе с этим и как их избежать. Также Антон предлагает углубиться в технические детали, чтобы лучше понимать, как работает HTTP-контекст. Он напоминает зрителям оставлять лайки, подписаться на канал и проверять описание видео, где располагается ссылка на курс по C#. В примере приложения с тремя конечными точками, одна из которых предназначена для отображения текущего аутентифицированного пользователя, Антон использует mock-схему аутентификации. Он обращает внимание на то, что если зрители не знакомы с аутентификацией, им стоит обратиться к предыдущим видео. В видео также рассматривается проблема с сервисом, который вызывает исключение из-за отсутствия HTTP-контекста.
😉 Проблема с доступом к HTTP-контексту в фоновых сервисах
Антон продолжает рассказ о проблеме, возникающей при попытке доступа к HTTP-контексту из фоновых сервисов. Он демонстрирует, как это может произойти, используя пример кода, в котором бизнес-логика, которая раньше работала в рамках HTTP-запроса, пытается выполниться вне этого контекста. В видео показано, что при попытке уведомления пользователя из фонового сервиса возникает исключение из-за отсутствия ссылки на HTTP-контекст. Антон подчеркивает важность понимания, что бизнес-логика должна быть независима от сервера ASP.NET Core и не должна зависеть от сервисов, предназначенных только для этого сервера, таких как HTTPContextAccessor.
🤔 Подробное объяснение работы HTTP-контекста и его доступности
В этом отрывке Антон углубляется в детали работы HTTP-контекста в ASP.NET Core. Он рассматривает процессы создания, обработки запроса и уничтожения контекста, используя классы и методы из библиотеки Castle.Core. Антон объясняет, что HTTPContextAccessor зарегистрирован в контейнере внедрения зависимостей как Singleton, но его скоуп определяется AsyncLocal, который связывает контекст с конкретным запросом. Он также демонстрирует, как и когда HTTP-контекст устанавливается и удаляется из HTTPContextAccessor, что является ключевым моментом для понимания проблемы, рассмотренной в видео.
🙂 Заключение и рекомендации для избегания проблем
Антон завершает видео с рекомендациями по избеганию подобных проблем с HTTP-контекстом. Он подчеркивает, что бизнес-логика должна быть независима от веб-сервера и не должна зависеть от сервисов, специфичных для ASP.NET Core. Антон напоминает, что все необходимые данные должны быть извлечены до входа в конечную точку или обработчик контроллера. Он также благодарит зрителей за просмотр, предлагает присоединиться к своему серверу Discord, поддержать его на Patreon и просматривает курсы по C#.
Mindmap
Keywords
💡IH HTTP контекст
💡Асинхронный локальный (Async Local)
💡Dependency Injection (DI)
💡Background Service
💡Middleware
💡Singleton
💡Authentication
💡Hosting Abstractions
💡Default HTTP Context
💡HTTP Context Accessor
💡ASP.NET Core
Highlights
Anton introduces the topic of the IH HTTP context accessor and its potential issues.
Discussion on how to avoid problems related to the IH HTTP context accessor.
Explanation of the HTTP context and its lifecycle within an ASP.NET Core application.
Demonstration of a sample application with endpoints and an authentication handler.
Introduction to the concept of 'fire and forget' tasks and their impact on HTTP context.
Observation of a failed attempt to access the HTTP context outside of a request context.
Explanation of why the HTTP context is null in certain scenarios, leading to exceptions.
Illustration of how business logic should be designed to be independent of the ASP.NET Core framework.
Discussion on the importance of not relying on framework-specific services like the IH HTTP context accessor.
Presentation of a more realistic example where the same business logic is used inside and outside of an HTTP request.
Analysis of the background notification service and its interaction with the HTTP context.
Explanation of the three key concepts to avoid encountering issues with the IH HTTP context accessor.
Deep dive into the internal workings of the IH HTTP context accessor and its registration as a Singleton service.
Discussion on the role of Async Local in scoping the HTTP context to a specific request.
Inspection of the code where the HTTP context is placed into the IH HTTP context accessor.
Summary of the lifecycle of the HTTP context within the middleware pipeline.
Advice on programming business logic as if it's independent of the web server to avoid issues.
Conclusion and call to action for viewers to engage with the content and support the channel.
Transcripts
welcome to the rocking YouTube channel
my name is Anton and today we're going
to be talking about the IH HTTP context
accessor what kind of problems you can
run into it how to avoid these problems
we're going to be taking a look at some
under the hood stuff of how does it work
how does the HTTP context appear in
there Etc basically trying to become
better Engineers with better awareness
of the tools that we are using don't
forget if you're enjoying the video
leave a like subscribe make sure to
check out the description I have a c
course out if you want to know c as I do
it I highly recommend you go ahead and
check it out with that let's go ahead
and get started here we have the sample
application with a couple of files
nothing too extreme we have the program
CS file and mainly we have three
endpoints and this root endpoint is to
outline the current user that is signed
in the user that is signed in I am
mocking an authentication schema with
this always authenticated authentication
Handler if you don't understand about
Authentication you're in luck I have
quite a few episodes on it go ahead and
check out the description basically all
this means is that we're always going to
be signed in as this user you don't need
to call login or anything like that
amongst other services we're adding the
ad HTTP context accessor and then we're
registering a Singleton service some
kind of business logic and then a
background notification service which is
going to be a hosted service so it's
something that is running in the
background if I open up the terminal the
application is already running and if we
just take a look at the roots we have
this test user with the test email
coming back to the code we're going to
take a look at the first endpoint and
this a service which is registered as a
Singleton and it has a function that is
something slowly sync now this example
is copied from this Outline by David fer
which explains why this service is bad
but I don't think this example actually
illustrates the point of how you can run
in into this issue blindly so that's
what we're going to be learning about
today nevertheless first of all let's
observe the issue this function is going
to be a fire and forget task which we're
going to wait for a little bit and then
we're going to try to access the HTTP
context and we access it by hitting the
dummy end point and we kick off a task
here coming back over here let's go
ahead and kick off dummy we we have okay
we come back if we take a look at the
console nothing is being printed it is
failing silently we don't actually see
anything if we open this up and I will
uncomment this and I will actually
output something to the logger so we can
actually see this failing the
application will restart I'll come back
over here I'll refresh and then coming
back over here we see the explosion
happening the reason the explosion is
happening is the HTTP context inside the
HTTP context accessor is null and that
is the exception that we're getting here
the reason it is null is because the
HTTP context represents the HTTP context
I don't know how else to say it other
than when the request starts that's when
the HTTP context is created and when the
request ends that's when the HTTP
context is disposed of we we'll take a
look at the code where that actually
happens before we do the Deep diving
we're going to take a look at some code
that you might write in the future that
will essentially make you encounter this
issue so here is some kind of service it
is a class with a function some Services
get injected into here and what we're
trying to do is do something with the
user at this point we're notifying the
user but it can be literally anything
the point is you're trying to access the
user the user exists on the HTTP context
in the MVC world the claims principle
wasn't actually injectable so the only
way that you can get the user is through
the HTTP context so you would have your
business logic rely on the ihtp context
accessor and you would attempt to do
something like this if we come back to
program CS we will have the notify
service over here we have the business
logic and we notify the user now because
we're awaiting over here everything is
going to run smoothly and that is
basically the experience that you would
have so let's open up the terminal stuff
is going to get restarted let's go ahead
and notify everything is going to be
okay and notification is successful some
time is going to pass and what you
actually want to have is a background
service that is going to pull the
database check some State and then if
that states meet some kind of rules it
is going to try to notify the user so
you set up your background service you
register it as a hosted service and then
as you're getting a signal to notify the
user again this can be a query to the
database in the loop all I'm doing here
is passing a message down a channel I'm
then creating a scope and then I'm
retrieving the business logic because
that logic of notifying a user I want
that to be reusable and then I notify
the user if I go to program CS we have
the background notification service over
here and I write test into the
background notification service so
that's going to go into this channel
writer over here and then this channel
reader is going to pick up the message
okay so that's basically how it's going
to go into here with this example it's a
little bit more of a realistic example
of what is being highlighted over here
you start off with logic that was
running during an HTTP request and then
you want to execute that same logic
outside of an HTTP request and that is
how you essentially encounter this issue
so
notify DBS if I open up well we'll see
that we again encounter the N reference
exception on the IH HTTP context
accessor at this point if you're still
listening the audience is pretty much
split into two parts the first one that
has been taught the lesson or has
encountered this issue and learned the
lesson or the second part that is maybe
a little bit blind first time you hear
about this ihtp context accessor what do
you need to understand to not encounter
this issue and similar issues there will
be three things first is the concept of
the HTTP server and that is the asp.net
core application that you're programming
second is the business logic this
business logic should be able to exist
outside of the asp.net core server
generally what happens is you take the
business logic and you register it with
the dependency injection container and
then that business logic will get
injected into your MVC controllers or
endpoints and at that point everything
seems to be fused together you need to
understand that your business logic that
is even though it is injected through
the dependency injection controller
should not rely on services that are
built for the asp.net core framework the
ihtp context accessor is an example of a
service which is used for the asp.net
core framework to do HTTP web server
things as you receive the request it's
going to go through the middleware
pipeline and at that point you need to
extract all the information that you can
get you're essentially preparing the
scene and then you're injecting it all
into the business logic and you're
setting up your business logic to then
execute so you still have your web
server you still have your business
logic controllers and endpoints is that
place where you transfer from the web
server world into your business logic
World As Long as You Follow that rule
you will never encounter an issue like
this where you will spot uh this belongs
to the web server because there is some
awareness of HTTP RPC websockets
whatever other web service notion there
might be you want to take that out let's
come back to the code and actually
inspect what is the IH HTTP context
accessor and how is it set so first of
all let's unpackage add HTTP context
accessor and here we will see the HTTP
context accessor being registered and
it's actually registered as a Singleton
service so even though it exists only
for the scope of the HT CTP request it
itself is not a sculpt service the thing
that actually gives the ihtp context
accessor its scopen is this async local
which is a pretty loaded concept and in
order to understand how it actually
works under the hood deserves a video of
its own looking at this all you need to
understand is asyn local is the thing
that will make the HTTP context holder
the thing that holds the HTTP context
for this specific request that is being
made to the server because that request
will be executed in an async task async
local is the thing which is going to
scope this HTTP context to the task or
to the async context which is going to
be processing the request with that
let's back out back into program Cs and
we're going to understand at which point
the HTTP context is actually placed into
the I HTTP context accessor what I'm
about to do here you can get more
information from the castol video I did
where we try to understand if it's worth
building our own web framework on top of
cro similar to asp.net core the answer
to which is no but nevertheless we learn
things about Castrol and how to interact
with krol here I'm just going to show
you how to walk down to Castrol from
your esp. net core application let's go
ahead and decompile run and here we'll
have this hosting abstractions host
extensions run and here again down to
run a Sync here is where the web server
Starts Here It basically just waits for
the web server to shut down so until you
actually shut down the server the
execution is going to be paused here
we're going to go into start a sync and
this is on the interface so we want to
go to the implementation of the host
class in here we will go through
execution up until we reach a loop where
we have a bunch of hosted Services if we
come back to program CS where I register
the background notification service
which is a background service which is
still a hosted service the krol server
is a background service which is running
in the background and servicing your
requests coming back to the host we have
the hosted Services over here and start
async is being called specifically the
castral web server is a generic web host
server and here again we will scroll
down up until we have this application
which is essenti
the request delegate if you know what
the request delegate your web server
your asp.net core app is essentially
just a configured middleware pipeline
which will get passed down into this
hosting application the stard a sync
over here is called on the server so I
server or implementations for I server
will be the Cal server and Cal server
internal implementation and then you can
also have an is HTTP server okay we are
particularly interested or not so
interested in the actual classes but
rather the thing that is passed down to
the castol server so coming back over
here we have stard a sync and HTTP
application is being passed down into it
we're going to go into host application
and down here we will first have create
context we will then have process
request async and then dispose of
context to summarize these three
functions the create context is when you
are receiving the request so you doing
some setup you're then processing the
request and that's going to be the
underscore application which is again
just your middleware pipeline and then
you have the dispose context which is
basically going to tear everything down
in these contexts what is being used is
a default HTTP context which is a
service which is registered at the point
of this create Builder so when you
initially set up your Builder this
service already exists internally and
I've gone to bad Services over here but
I want to be over here okay and sorry I
wasn't talking about the default HTTP
context is the default HTTP context
Factory this is a service which exists
from the beginning over here when you
call create Builder Okay the default
HTTP context Factory if we take a look
at the create function that is going to
be inside the default HTTP context
factoring so just this class when we
create the HTTP cont context so the
default HTTP context over here it goes
through an initialization process the
default HTTP context Factory because it
comes from the same dependency injection
container where you're registering your
services it is attempting to extract an
HTTP context accessor from that same
container and you can see that this HTTP
context accessor if you never call add
HTTP context accessor it is actually
going to be null so this logic has to
account for that fact if the service is
present this is actually just going to
go ahead and set the HTTP context on the
HTTP context accessor okay so this
answers the question of when does the
HTTP context actually gets placed into
the HTTP context accessor and how long
does it actually exist there if we again
come back to the host application during
the setup of the request the ihtp
context accessor service actually gets
prepared and loaded with the created
HTTP context over here you then place
the HTTP context into the middleware
pipeline so it gets processed and after
which if we have the HTTP context
accessor we clear it from the context
and the dispose on the HTTP context
Factory this is where it's actually
going to clear it away from the HTTP
context accessor itself now I've
probably said HTTP context accessor like
a gazillion times but all you need to
know is that HTTP context accessor is
set up and the HTTP context inside the
HTTP context accessor gets wiped out
before and after the HTTP context
actually gets sent into your middleware
with that I think it's a good time to
end the video remember even though your
business logic sits inside the web
server you want to program it as if it
doesn't know anything about the web
server this way you're never going to
encounter a problem like relying on the
ihtp context access to get a user or
some kind of other state from the HTTP
request make sure all of that
information is extracted before or at
the point of you entering your endpoint
or action or Handler on the controller
razor page whatever it is that endpoint
action or Handler is the transition from
the HTTP server world into your business
logic as always if you enjoyed the video
don't forget to leave a like subscribe
if you have any questions make sure to
leave them in the comment section go
join my Discord server and if you want
the code for this video as well as my
other videos come support me on Patron I
will really appreciate it and a very
very big thank you to all of my current
patreon supporters you help me make
these videos don't forget to check out
my C course again thank you for watching
have a good day
Browse More Related Video
5.0 / 5 (0 votes)