Как бороться с тайм-аутом сеанса (или токеном с истекшим сроком действия), когда нет маршрутизации по ссылке в angular 4

У меня есть один очень распространенный сценарий для токена с истекшим сроком действия, как показано ниже, Kindle помогает мне справиться с этим.

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

однако, скажем, у меня есть ссылка обновления (которая обновляет запись таблицы, вызывая новый HTTP-запрос на получение) на той же странице, которая просто обновляет записи таблицы (она не обновляет всю страницу). если я нахожусь на одной странице более 30 минут и нажимаю кнопку обновления, как проверить срок действия токена или нет. поскольку в этом сценарии обновления маршрутизация не используется, поэтому активная защита не будет проверять, истек ли срок действия токена.

Не могли бы вы подсказать мне, как справиться с этим вариантом использования.

Заранее спасибо !!!


person Nikky    schedule 06.09.2018    source источник
comment
Рассматривал возможность задать аналогичный вопрос, хотя я хочу перенаправить пользователя на другую страницу, когда происходит тайм-аут сеанса.   -  person Robert Love    schedule 06.09.2018
comment
Вы говорите о кнопке обновления окна браузера или о чем-то, что есть на вашей странице, что в основном является вашей ссылкой обновления @Nikky   -  person Vaibhav Kumar Goyal    schedule 06.09.2018


Ответы (2)


введите описание изображения здесь

В нашей среде, чтобы обеспечить наилучший UX, пользователи не перенаправляются на страницу входа по истечении сеанса.

Вместо этого вся страница размыта, и отображается модальное окно, требующее ввода пароля и содержащее кнопку отправки, как указано выше.

Основными преимуществами такого подхода являются:

  1. Избегайте разочарования из-за потери несохраненной работы во время перенаправления.
  2. Более кажущийся опыт повторной аутентификации.

Подобно некоторым ответам, описанным здесь - https://ux.stackexchange.com/questions/7195/best-practices-for-warning-of-session-expiration

Как добиться этого в Angular?

  1. При успешном первом входе в систему напишите дату/время истечения срока действия сеанса в localStorage, например new Date() + 30 minutes.
  2. Вставьте, например, authentication.service.ts на уровне приложения, которое будет иметь setInterval(() => checkSessionTimeout(), e.g every 1 minute) внутри своего конструктора. Такой подход гарантирует, что этот метод будет работать и на новых вкладках/окнах.
  3. Создайте метод checkSessionTimeout(), который выводит, сколько минут осталось до истечения времени ожидания сеанса, и запишите его в переменную в authentication.service.ts, например sessionTimeoutIn: number;.
  4. Создайте компонент, который будет содержать модальное окно повторной аутентификации, как показано на изображении выше. Внедрите этот компонент на уровне приложения с помощью <app-re-authenticate-modal *ngIf="authenticationService.sessionTimeoutIn <= 0"></app-re-authenticate-modal>
  5. Для эффекта размытия добавьте в body/main класс с [class.blur]="authenticationService.sessionTimeoutIn <= 0"
  6. Для еще большего удобства создайте div, который толкает main/body и входит в представление сверху, содержащее это, которым можно управлять с помощью <div *ngIf="authenticationService.sessionTimeoutIn > 0 && authenticationService.sessionTimeoutIn <= 2"></div>:

введите описание изображения здесь

После этого пользователь не должен пытаться делать что-либо, кроме повторной аутентификации, и вы все равно можете использовать свои AuthenticationGuards.

Надеюсь, поможет.

person Uğur Dinç    schedule 06.09.2018
comment
Ницца! Этот ответ очень полезен, однако я чего-то не понимаю. Как определить неактивность сеанса? Что, если срок действия токена истекает через 2 минуты (как в вашем примере), но пользователь не был неактивным или что-то еще. Мы бы не хотели показывать этот div в пункте №6. Как бы вы это определили? - person chris; 04.05.2020
comment
@chris Это будет зависеть от ваших конкретных требований, но в моем случае наше определение бездействия было таким: прошло ли 30 минут с момента входа в систему? И в отличие от моих требований, если вы заинтересованы в сохранении сеанса, например, для каждого вызова API, вы можете иметь HttpInterceptor, который сбрасывает часы после каждого вызова API. Или еще один шаг вперед, я думаю, вы могли бы иметь прослушиватель событий мыши на глобальном уровне, который также сбрасывает часы, если ваше определение поддерживало сеанс, пока пользователь что-то делает. - person Uğur Dinç; 04.05.2020
comment
это имеет смысл. Думаю, я могу совместить это с реализацией refresh token, спасибо! - person chris; 04.05.2020

Внутри вашей защиты маршрута CanActivate вы можете возвращать либо Promise<boolean>, либо Observable<boolean>, либо boolean.

Но внутри того же файла защиты вы также можете полагаться на службу, которая возвращает вам true или false в зависимости от того, истек ли срок действия токена или нет. И это, в свою очередь, то, что вы можете вернуть из своей гвардии.

Предположим, что AuthService проверяет, не истек ли срок действия токена аутентификации. И служба данных получает данные для вас.

Теперь, прежде чем обновлять эти данные, вы можете снова проверить их, внедрив этот AuthService в свой DataService в качестве зависимости, а затем проверив, истек ли срок действия токена или нет.

В качестве альтернативы ваш API может проверить, был ли этот запрос аутентифицирован или нет. Для этого вам потребуется отправлять заголовок авторизации с каждым запросом. В таком случае вы можете использовать HttpInterceptor. Этот перехватчик будет перехватывать каждый исходящий запрос, чтобы проверить, присутствует ли в нем заголовок Authorization. Если он присутствует, только тогда он позволит продолжить выполнение запроса. Если нет, вы можете сделать все необходимое, вернув пользователя обратно на страницу входа.

person SiddAjmera    schedule 06.09.2018