All streams
Search
Write a publication
Pull to refresh
3
0
Роман Букин @nomoreload

BackEnd разработчик ASP.NET Core.

Send message
Interceptor'ы- киллер фича. По сути middleware, который работают как на отправку, так и на получение. Отличная штука. Не надо больше сервисы-обвязки городить для того, чтобы токены в заголовки проставлять.

Ну IdentityServer — это OAuth2.0/OpenIdConnect сервер, реализованный по спецификациям.
ImplicitFlow — это стандартный flow из спецификации OAuth2.0 и OpenIdConnect.
Работает следующим образом:


  1. Пользователь открывает https://example.com (FrontEnd)
  2. Фронт в процессе инициализации залазит в localStorage в поисках токена. Если токен найден, пытается получить информацию о пользователе, обращаясь к UserInfoEndpoint. Если ответ не 200, то стираем всю информацию об авторизации и считаем пользователя неавторизованным, если же 200ка, то сохраняем информацию о пользователе в TypeScript-сервисе (который Angular потом инжектит куда нужно) и работаем как обычно.
  3. Если пользователь не авторизован, открываем ему страницу входа с кнопкой "Войти". По нажатию на кнопку, юзер отправляется на сервер авторизации (он же IdentityServer) https://identity.example.com через Implicit flow.
    Это будет запрос вида:
    GET https://identity.example.com/connect/authorize?response_type=id_token token&client_id=frontend-app&redirect_uri=https://example.com/login-callback&scope=openid profile api_v1&nonce=чего-то
  4. Попадая на IdentityServer, пользователь авторизуется через логин-пароль/вк/google/facebook/whatever you want. После этого его редиректит на https://example.com/login-callback, где его ожидает сервис, отвечающий за авторизацию. Т.е. фронт в данном случае у нас перезагружается полностью (ну или нет, если кэширование настроили). На колбэке сидит сервис, который записывает информацию о токенах в localstorage, и, который после этого опять же дёргает метод для получения информации о пользователе (который был в п.2), только после успешного выполнения которого мы продолжаем работу.
  5. По ходу работы у нас в фоне периодически выполняются обращения к IdentityServer за новыми токенами. И вот тут самое важное. До тех пор, пока сессия на IdentityServer открыта, повторная авторизация в нём не требуется и он, глядя, что с куками всё ок — выдаёт новые токены, попутно обновляя информацию о юзере и устанавливая новые куки, тем самым продлевая время жизни сессии.

Резюмируя вышеописанное. До тех пор пока открыта сессия на IdentityServer, пользователь без проблем будет пользоваться приложением. Может возникнуть вопрос по п.2 — а что если юзер ушёл на 2 часа, закрыв приложение, а сессия валидна 8 часов? Что будет при повторном посещении? А будет вот что — фронт увидит, что токен протух, сотрёт его и редиректнет пользователя на страницу входа. Он нажмёт кнопку "Войти" и дальше просто последует череда редиректов с попутным обновлением сессии на IdentityServer.


А дальше приложение просто делает запросы, цепляя в заголовок access_token, который backend уже сам проверяет, периодически обращаясь к IdentityServer и кэшируя ответы, чтобы сильно его запросами не спамить.


Как-то так)

К счастью, больше не нужно делать такой велосипед) В Angular 4.3 завезли Http клиент новый и HttpInterceptor'ы к нему. По сути middleware. Можно все запросы обрабатывать до, во время отправки, во время и после получения ответа. В частности типичный юзкейс — установка заголовков авторизации.
Повторно токены получаем через silent renew. Для пользователя всё прозрачно — он авторизуется на IdentityServer, а далее, до тех пор пока активна сессия на стороне IdentityServer, токены скрытно обновляются. Никаких попапов, редиректов или чего-то там ещё. Если в промежутке между обновлениями были внесены изменения в учётную запись пользователя (добавили новую роль, например), то они отражаются в токене при следующем его обновлении, и на основе новых данных реактивно перестраивается фронт. Типа не было кнопочек каких-то, оппа- появились :-) Пользователи довольны, самое главное) Но чтоб такой трюк провернуть, нужно при каждой валидация кук на IdentityServer'е, актуализировать их. Тайм-аут обновления на фронте — 5 минут, срок жизни access_token — 60 минут. Как-то так
У нас backend на ASP.NET Core, а вот фронт как раз на Angular 4. На бэке — IdentityServer4, на фронте oidc-client-js. Те же яйца, только в профиль. Тоже JWT юзаем. На бэке включены CORS, а фронт по ImplicitFlow работает с silent renew. Таким образом, отпадает необходимость в refresh-token+можно относительно быстро отреагировать на изменение прав пользователя. Если на IdentityServer'е пользователя заблокируют — его просто выпрет из фронта. Или если новых фич добавят — они у него просто сами в интерфейсе появятся. Всё сертифицировано OpenIdConnect. По мне, так на фронте лучше не хранить refresh_token без возможности инвалидации.
Не пиара ради. На днях как раз сделал реализацию спецификации для .NET Standard 2.0
github.com/NoMoreLoad/CoreSpecs
Забавно получилось)

Единственная проблема, с которой реально столкнулись — это то, что в документации, на момент деплоя не был освещён момент по поводу работы за обратным прокси (UseForwardedHeaders). Но на IIS всё волшебным образом работало. Почитали исходники модуля (слава MIT лицензии), который Kestrel с IIS интегрирует, там и нашли перенаправление заголовков. Единственное, нужно не забыть их перенаправление и в nginx'е настроить, и будет счастье))
Работаем без виртуализации. Полгода, полёт отличный.

Information

Rating
Does not participate
Location
Краснодар, Краснодарский край, Россия
Date of birth
Registered
Activity