fix(#518): multiple tabs logout

pull/192/head
Rakov 3 years ago
parent 5815744de4
commit f31a83629d
  1. 27924
      package-lock.json
  2. 1
      package.json
  3. 1
      src/features/AuthStore/helpers.tsx
  4. 24
      src/features/AuthStore/hooks/useAuth.tsx
  5. 4
      src/requests/checkDevice.tsx

27924
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -27,6 +27,7 @@
"@stripe/stripe-js": "^1.13.2", "@stripe/stripe-js": "^1.13.2",
"babel-polyfill": "^6.26.0", "babel-polyfill": "^6.26.0",
"date-fns": "^2.14.0", "date-fns": "^2.14.0",
"dueljs": "^1.2.7",
"eslint-plugin-typescript-sort-keys": "^2.3.0", "eslint-plugin-typescript-sort-keys": "^2.3.0",
"history": "^4.10.1", "history": "^4.10.1",
"hls.js": "^1.1.1", "hls.js": "^1.1.1",

@ -61,7 +61,6 @@ const redirectUrl = () => {
export const getClientSettings = (): Settings => ({ export const getClientSettings = (): Settings => ({
authority: AUTH_SERVICE, authority: AUTH_SERVICE,
automaticSilentRenew: true,
client_id: client.auth.clientId, client_id: client.auth.clientId,
filterProtocolClaims: false, filterProtocolClaims: false,
loadUserInfo: false, loadUserInfo: false,

@ -7,6 +7,8 @@ import {
import { useHistory } from 'react-router' import { useHistory } from 'react-router'
import type { User } from 'oidc-client' import type { User } from 'oidc-client'
// @ts-ignore
import duel from 'dueljs'
import isString from 'lodash/isString' import isString from 'lodash/isString'
import isBoolean from 'lodash/isBoolean' import isBoolean from 'lodash/isBoolean'
@ -238,28 +240,24 @@ export const useAuth = () => {
setIsNewDeviceLogin, setIsNewDeviceLogin,
]) ])
duel.channel('active_page') // поле в LS, определяющее активность вкладки
useEffect(() => { useEffect(() => {
// попытаемся обновить токен используя refresh_token // попытаемся обновить токен используя refresh_token
const tryRenewToken = () => { const tryRenewToken = () => {
const tokenLastUpdated = Number(localStorage.getItem('token_updated')) // библиотека oidc-client не поддерживает обновление токена только на 1 вкладке
// предотвращаем одновременное обновление токена в разных окнах/вкладках // @ts-ignore
const needRenewToken = Date.now() - tokenLastUpdated >= 2 * 1e3 if (window.isMaster()) {
userManager.signinSilent().catch(logout)
if (!needRenewToken) return }
localStorage.setItem('token_updated', String(Date.now()))
userManager.signinSilent()
.catch(logout)
} }
// если запросы вернули 401 | 403 // если запросы вернули 401 | 403
window.addEventListener('FORBIDDEN_REQUEST', tryRenewToken) window.addEventListener('FORBIDDEN_REQUEST', tryRenewToken)
// и если токен истек // и если токен истекает (по дефолту за 60 секунд)
userManager.events.addAccessTokenExpired(tryRenewToken) userManager.events.addAccessTokenExpiring(tryRenewToken)
return () => { return () => {
window.removeEventListener('FORBIDDEN_REQUEST', tryRenewToken) window.removeEventListener('FORBIDDEN_REQUEST', tryRenewToken)
userManager.events.removeAccessTokenExpired(tryRenewToken) userManager.events.removeAccessTokenExpiring(tryRenewToken)
} }
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [logout]) }, [logout])

@ -1,4 +1,4 @@
import { AUTH_SERVICE } from '../config/routes' import { API_ROOT } from 'features/AuthServiceApp/config/routes'
export type FailedResponse = { export type FailedResponse = {
error?: string, error?: string,
@ -10,7 +10,7 @@ export type SuccessResponse = {
} }
export const checkDevice = async (token: string) => { export const checkDevice = async (token: string) => {
const url = `${AUTH_SERVICE}/authorize/check-device?access_token=${token}` const url = `${API_ROOT}/authorize/check-device?access_token=${token}`
const config = { const config = {
method: 'GET', method: 'GET',

Loading…
Cancel
Save