fix(safari): safari logout fix

insport.live
Rakov 2 years ago
parent ccb265cb2e
commit 4b64a17b02
  1. 23
      public/silent-refresh.html
  2. 38
      src/features/AuthStore/hooks/useAuth.tsx
  3. 13
      src/helpers/token/index.tsx

@ -1,15 +1,28 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<title></title> <title></title>
</head> </head>
<body> <body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/oidc-client/1.11.5/oidc-client.min.js" integrity="sha512-pGtU1n/6GJ8fu6bjYVGIOT9Dphaw5IWPwVlqkpvVgqBxFkvdNbytUh0H8AP15NYF777P4D3XEeA/uDWFCpSQ1g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/oidc-client/1.11.5/oidc-client.min.js"
integrity="sha512-pGtU1n/6GJ8fu6bjYVGIOT9Dphaw5IWPwVlqkpvVgqBxFkvdNbytUh0H8AP15NYF777P4D3XEeA/uDWFCpSQ1g=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script> <script>
new Oidc.UserManager().signinSilentCallback() new Oidc.UserManager().signinSilentCallback()
.catch((err) => { // обновляем рефреш токен в локалсторадже
console.error('OIDC: silent refresh callback error', err); // так как safari не дает доступ к кукам
}); .then(() => {
const refreshToken = localStorage.getItem('refresh_token');
if (refreshToken) {
localStorage.setItem('refresh_token', new URLSearchParams(document.location.search).get('refresh_token'));
}
})
.catch((err) => {
console.error('OIDC: silent refresh callback error', err);
});
</script> </script>
</body> </body>
</html>
</html>

@ -14,7 +14,11 @@ import isString from 'lodash/isString'
import isBoolean from 'lodash/isBoolean' import isBoolean from 'lodash/isBoolean'
import includes from 'lodash/includes' import includes from 'lodash/includes'
import { PAGES } from 'config' import {
PAGES,
isFacrClient,
isLffClient,
} from 'config'
import { import {
addLanguageUrlParam, addLanguageUrlParam,
@ -24,6 +28,10 @@ import {
setCookie, setCookie,
removeCookie, removeCookie,
isMatchPage, isMatchPage,
REFRESH_TOKEN_KEY,
removeRefreshToken,
writeRefreshToken,
readRefreshToken,
} from 'helpers' } from 'helpers'
import { import {
@ -77,6 +85,7 @@ export const useAuth = () => {
userManager.signoutRedirect({ post_logout_redirect_uri: urlWithLang }) userManager.signoutRedirect({ post_logout_redirect_uri: urlWithLang })
}) })
removeToken() removeToken()
removeRefreshToken()
if (key !== 'saveToken') { if (key !== 'saveToken') {
removeCookie('access_token') removeCookie('access_token')
} }
@ -158,12 +167,18 @@ export const useAuth = () => {
} }
} }
const signinRedirectCallback = useCallback(() => { const signinRedirectCallback = useCallback(async (refreshToken: string | null) => {
setPage(history.location.pathname) setPage(history.location.pathname)
userManager.signinRedirectCallback() userManager.signinRedirectCallback()
.then((loadedUser) => { .then((loadedUser) => {
storeUser(loadedUser) storeUser(loadedUser)
if (
refreshToken
&& (isLffClient || isFacrClient)
) writeRefreshToken(refreshToken)
queryParamStorage.clear() queryParamStorage.clear()
if (page.includes(PAGES.useraccount)) { if (page.includes(PAGES.useraccount)) {
history.push(PAGES.home) history.push(PAGES.home)
@ -175,7 +190,7 @@ export const useAuth = () => {
setPage('') setPage('')
setSearch('') setSearch('')
}).catch(login) }).catch(login)
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [ }, [
login, login,
storeUser, storeUser,
@ -187,11 +202,14 @@ export const useAuth = () => {
const searchToken = urlSearch.get('access_token') const searchToken = urlSearch.get('access_token')
const searchRefToken = urlSearch.get('id_token') const searchRefToken = urlSearch.get('id_token')
const searchExp = urlSearch.get('expires_in') const searchExp = urlSearch.get('expires_in')
const refreshToken = urlSearch.get(REFRESH_TOKEN_KEY)
const isRedirectedBackFromAuthProvider = Boolean(searchToken && searchRefToken && searchExp) const isRedirectedBackFromAuthProvider = Boolean(searchToken && searchRefToken && searchExp)
isRedirectedBackFromAuthProvider ? signinRedirectCallback() : checkUser() isRedirectedBackFromAuthProvider
// eslint-disable-next-line react-hooks/exhaustive-deps ? signinRedirectCallback(refreshToken)
: checkUser()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [ }, [
checkUser, checkUser,
signinRedirectCallback, signinRedirectCallback,
@ -221,7 +239,7 @@ export const useAuth = () => {
}, [reChekNewDevice]) }, [reChekNewDevice])
useEffect(() => { useEffect(() => {
if (!needCheckNewDeviсe && !user) return undefined if (!needCheckNewDeviсe || !user) return undefined
const startCheckDevice = setInterval(checkNewDevice, 20000) const startCheckDevice = setInterval(checkNewDevice, 20000)
isNewDeviceLogin && clearInterval(startCheckDevice) isNewDeviceLogin && clearInterval(startCheckDevice)
return () => clearInterval(startCheckDevice) return () => clearInterval(startCheckDevice)
@ -240,7 +258,13 @@ export const useAuth = () => {
// библиотека oidc-client не поддерживает обновление токена только на 1 вкладке // библиотека oidc-client не поддерживает обновление токена только на 1 вкладке
// @ts-ignore // @ts-ignore
if (window.isMaster()) { if (window.isMaster()) {
userManager.signinSilent().catch(logout) // safari ограничивает доступ к куке через крос доменные запросы
// передаем рефреш токен через квери параметры
userManager.signinSilent({
extraQueryParams: (isLffClient || isFacrClient) && {
refresh_token: readRefreshToken(),
},
}).catch(logout)
} }
} }
// если запросы вернули 401 | 403 // если запросы вернули 401 | 403

@ -1,4 +1,5 @@
export const TOKEN_KEY = 'token' export const TOKEN_KEY = 'token'
export const REFRESH_TOKEN_KEY = 'refresh_token'
export const readToken = () => ( export const readToken = () => (
localStorage.getItem(TOKEN_KEY) localStorage.getItem(TOKEN_KEY)
@ -11,3 +12,15 @@ export const writeToken = (token: string) => (
export const removeToken = () => ( export const removeToken = () => (
localStorage.removeItem(TOKEN_KEY) localStorage.removeItem(TOKEN_KEY)
) )
export const removeRefreshToken = () => {
localStorage.removeItem(REFRESH_TOKEN_KEY)
}
export const writeRefreshToken = (token: string) => (
localStorage.setItem(REFRESH_TOKEN_KEY, token)
)
export const readRefreshToken = () => (
localStorage.getItem(REFRESH_TOKEN_KEY)
)

Loading…
Cancel
Save