From 17984cc89e43bd993e85c26f7882be367d7986db Mon Sep 17 00:00:00 2001 From: siya Date: Thu, 14 May 2020 14:31:21 +0200 Subject: [PATCH 1/7] able to enchange refresh token for access token. Will do testing --- src/lib/createAuthContext.js | 20 +++++++++-- .../helpers/exchangeRefreshForAccessToken.js | 35 +++++++++++++++++++ 2 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 src/lib/helpers/exchangeRefreshForAccessToken.js diff --git a/src/lib/createAuthContext.js b/src/lib/createAuthContext.js index a2bfbb3..88e19ca 100644 --- a/src/lib/createAuthContext.js +++ b/src/lib/createAuthContext.js @@ -39,8 +39,22 @@ export default ({ } const useToken = () => { - const { token } = useContext(context) - if (!token) { + const { token, setAccessToke } = useContext(context) + if (token) { + const now = new Date() + const elapsed = now.getTime() - new Date(token.expires_at).getTime() + const slack = 10 + console.log('now.getTime()',now.getTime()) + console.log('elapsed', elapsed) + if(elapsed > slack){ + console.log('token is old ',token) + return exhancgeRefreshTokenForAccessToken({clientId, clientSecret, tokenEndpoint, fetch , token }) + .then(response => { + setAccessToke(response) + }) + } + return token + } else { console.warn(`Trying to useToken() while not being authenticated.\nMake sure to useToken() only inside of an component.`) } return token @@ -81,7 +95,7 @@ export default ({ } return ( - + {children} ) diff --git a/src/lib/helpers/exchangeRefreshForAccessToken.js b/src/lib/helpers/exchangeRefreshForAccessToken.js new file mode 100644 index 0000000..290c6a4 --- /dev/null +++ b/src/lib/helpers/exchangeRefreshForAccessToken.js @@ -0,0 +1,35 @@ +export const exhancgeRefreshTokenForAccessToken = ({ clientId, clientSecret, tokenEndpoint, fetch = window.fetch, token }) => { + const payload = { + client_secret: clientSecret, + client_id: clientId, + grant_type: "refresh_token", + scope: "openid, profile", + refresh_token: token.refresh_token + }; + return fetch(tokenEndpoint, { + headers: { + 'Content-Type': 'application/json' + }, + method: 'POST', + body: JSON.stringify(payload) + }) + .then(r => { + if (!r.ok) { + throw new Error(`Token response not ok, status is ${r.status}, check the react-u5auth configuration (wrong provider or token endpoint?)`); + } + return r.json(); + }) + .then(token => { + const { expires_in } = token; + if (expires_in && Number.isFinite(expires_in)) { + const slackSeconds = 10; + // add 'expires_at', with the given slack + token.expires_at = new Date(new Date().getTime() + expires_in * 1000 - (slackSeconds * 1000)); + } + return token; + }) + .catch(err => { + console.error('ERR (fetch)', err); + throw err; + }); +} From 3136570f68f9d2328f4aa29a3faba944561a1911 Mon Sep 17 00:00:00 2001 From: siya Date: Thu, 14 May 2020 15:22:02 +0200 Subject: [PATCH 2/7] manage to do some testing on small intervals and it works and also fix some other bugs, might be ready for a merge --- src/App.js | 6 +++--- src/lib/createAuthContext.js | 12 +++++------- src/lib/helpers/exchangeRefreshForAccessToken.js | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/App.js b/src/App.js index 3d80c76..643171b 100644 --- a/src/App.js +++ b/src/App.js @@ -1,9 +1,9 @@ import React, {useState} from 'react' import createAuthContext from './lib/createAuthContext' -const clientId = process.env.REACT_APP_CLIENT_ID || "8cb4904ae5581ecc2b3a1774" -const clientSecret = process.env.REACT_APP_CLIENT_SECRET || "b683283462070edbac15a8fdab751ada0f501ab48a5f06aa20aee3be24eac9cc" -const provider = process.env.REACT_APP_PROVIDER || "https://authenticate.u5auth.com" +const clientId = process.env.REACT_APP_CLIENT_ID || "884222a97d5a7373be6d5be2" +const clientSecret = process.env.REACT_APP_CLIENT_SECRET || "b1d2d9f20d3313aa9da1acba55e7e05ebc72c48169265fc94a374906a13d1988" +const provider = process.env.REACT_APP_PROVIDER || "http://localhost:3020" const {AuthContext, Authenticated, useToken} = createAuthContext({ clientId, diff --git a/src/lib/createAuthContext.js b/src/lib/createAuthContext.js index 88e19ca..60d789e 100644 --- a/src/lib/createAuthContext.js +++ b/src/lib/createAuthContext.js @@ -5,6 +5,7 @@ import { fetchToken } from './helpers/fetchToken' import { removeCodeFromLocation } from './helpers/removeCodeFromLocation' import { getVerifierFromStorage } from './helpers/getVerifierFromStorage' import { removeVerifierFromStorage } from './helpers/removeVerifierFromStorage' +import {exchangeRefreshForAccessToken} from './helpers/exchangeRefreshForAccessToken' export default ({ clientId, @@ -39,18 +40,15 @@ export default ({ } const useToken = () => { - const { token, setAccessToke } = useContext(context) + const { token, setToken } = useContext(context) if (token) { const now = new Date() const elapsed = now.getTime() - new Date(token.expires_at).getTime() - const slack = 10 - console.log('now.getTime()',now.getTime()) - console.log('elapsed', elapsed) + const slack = 1000 if(elapsed > slack){ - console.log('token is old ',token) - return exhancgeRefreshTokenForAccessToken({clientId, clientSecret, tokenEndpoint, fetch , token }) + return exchangeRefreshForAccessToken({clientId, clientSecret, tokenEndpoint, fetch , token }) .then(response => { - setAccessToke(response) + setToken(response) }) } return token diff --git a/src/lib/helpers/exchangeRefreshForAccessToken.js b/src/lib/helpers/exchangeRefreshForAccessToken.js index 290c6a4..6c9fa61 100644 --- a/src/lib/helpers/exchangeRefreshForAccessToken.js +++ b/src/lib/helpers/exchangeRefreshForAccessToken.js @@ -1,4 +1,4 @@ -export const exhancgeRefreshTokenForAccessToken = ({ clientId, clientSecret, tokenEndpoint, fetch = window.fetch, token }) => { +export const exchangeRefreshForAccessToken = ({ clientId, clientSecret, tokenEndpoint, fetch = window.fetch, token }) => { const payload = { client_secret: clientSecret, client_id: clientId, From 925bc29eb1bf67589a635521f99072fd99077ec5 Mon Sep 17 00:00:00 2001 From: siya Date: Wed, 10 Jun 2020 16:35:08 +0200 Subject: [PATCH 3/7] stop using localhost --- src/App.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/App.js b/src/App.js index 643171b..3d80c76 100644 --- a/src/App.js +++ b/src/App.js @@ -1,9 +1,9 @@ import React, {useState} from 'react' import createAuthContext from './lib/createAuthContext' -const clientId = process.env.REACT_APP_CLIENT_ID || "884222a97d5a7373be6d5be2" -const clientSecret = process.env.REACT_APP_CLIENT_SECRET || "b1d2d9f20d3313aa9da1acba55e7e05ebc72c48169265fc94a374906a13d1988" -const provider = process.env.REACT_APP_PROVIDER || "http://localhost:3020" +const clientId = process.env.REACT_APP_CLIENT_ID || "8cb4904ae5581ecc2b3a1774" +const clientSecret = process.env.REACT_APP_CLIENT_SECRET || "b683283462070edbac15a8fdab751ada0f501ab48a5f06aa20aee3be24eac9cc" +const provider = process.env.REACT_APP_PROVIDER || "https://authenticate.u5auth.com" const {AuthContext, Authenticated, useToken} = createAuthContext({ clientId, From 1d232dbea4d6f5fed934657bdf218eed72ed7ac1 Mon Sep 17 00:00:00 2001 From: siya Date: Wed, 10 Jun 2020 18:03:51 +0200 Subject: [PATCH 4/7] added time interval to get new token before token expires if we have a refresh token --- src/lib/createAuthContext.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lib/createAuthContext.js b/src/lib/createAuthContext.js index 60d789e..e92a53b 100644 --- a/src/lib/createAuthContext.js +++ b/src/lib/createAuthContext.js @@ -44,7 +44,7 @@ export default ({ if (token) { const now = new Date() const elapsed = now.getTime() - new Date(token.expires_at).getTime() - const slack = 1000 + const slack = 10000 if(elapsed > slack){ return exchangeRefreshForAccessToken({clientId, clientSecret, tokenEndpoint, fetch , token }) .then(response => { @@ -68,6 +68,7 @@ export default ({ if (!token) { const code = getCodeFromLocation({ location: window.location }) const verifier = getVerifierFromStorage({ clientId, storage }) + const slackSeconds = 10 if (code && verifier) { fetchToken({ clientId, clientSecret, tokenEndpoint, code, verifier, fetch @@ -76,6 +77,9 @@ export default ({ .then(() => { removeCodeFromLocation() removeVerifierFromStorage({ clientId, storage }) + if(token.refresh_token) { + setInterval(useToken(),token.expires_at - (slackSeconds * 1000)) + } }) .catch(e => { console.error(e) From 245531f3323a65e8a703065b515cea3188762fbd Mon Sep 17 00:00:00 2001 From: siya Date: Wed, 10 Jun 2020 18:25:27 +0200 Subject: [PATCH 5/7] using the timer in correct place since I don't have token in useEffect. I don't fully undersntad why I don't have the token value there. --- src/lib/createAuthContext.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/lib/createAuthContext.js b/src/lib/createAuthContext.js index e92a53b..a9efdbe 100644 --- a/src/lib/createAuthContext.js +++ b/src/lib/createAuthContext.js @@ -45,11 +45,11 @@ export default ({ const now = new Date() const elapsed = now.getTime() - new Date(token.expires_at).getTime() const slack = 10000 - if(elapsed > slack){ - return exchangeRefreshForAccessToken({clientId, clientSecret, tokenEndpoint, fetch , token }) + if(token.refresh_token) { + setInterval(() =>exchangeRefreshForAccessToken({clientId, clientSecret, tokenEndpoint, fetch , token }) .then(response => { setToken(response) - }) + }),elapsed - slack) } return token } else { @@ -76,10 +76,7 @@ export default ({ .then(setToken) .then(() => { removeCodeFromLocation() - removeVerifierFromStorage({ clientId, storage }) - if(token.refresh_token) { - setInterval(useToken(),token.expires_at - (slackSeconds * 1000)) - } + removeVerifierFromStorage({ clientId, storage }) }) .catch(e => { console.error(e) From 9c6c871dfa252bacb293055bbddad5ce50eee67b Mon Sep 17 00:00:00 2001 From: siya Date: Mon, 15 Jun 2020 12:18:32 +0200 Subject: [PATCH 6/7] getting error Unhandled Rejection (Error): Token response not ok, status is 400, check the react-u5auth configuration (wrong provider or token endpoint?) but I do receive new tokens. Investigating the cause. In the file createAuthContext.js in line 53 time interval is going to be (elapsed - slack), i did it this way since I am testing. Also in line 47 its going to be (10000) for slack. Also changed the header content-type and also the body --- src/lib/createAuthContext.js | 7 ++++--- src/lib/helpers/exchangeRefreshForAccessToken.js | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/lib/createAuthContext.js b/src/lib/createAuthContext.js index a9efdbe..525fe63 100644 --- a/src/lib/createAuthContext.js +++ b/src/lib/createAuthContext.js @@ -43,13 +43,14 @@ export default ({ const { token, setToken } = useContext(context) if (token) { const now = new Date() - const elapsed = now.getTime() - new Date(token.expires_at).getTime() - const slack = 10000 + const elapsed = new Date(token.expires_at).getTime() - now.getTime() + const slack = elapsed + 10000 + console.log('djbfagkj') if(token.refresh_token) { setInterval(() =>exchangeRefreshForAccessToken({clientId, clientSecret, tokenEndpoint, fetch , token }) .then(response => { setToken(response) - }),elapsed - slack) + }),slack - elapsed ) } return token } else { diff --git a/src/lib/helpers/exchangeRefreshForAccessToken.js b/src/lib/helpers/exchangeRefreshForAccessToken.js index 6c9fa61..601f1a7 100644 --- a/src/lib/helpers/exchangeRefreshForAccessToken.js +++ b/src/lib/helpers/exchangeRefreshForAccessToken.js @@ -8,10 +8,10 @@ export const exchangeRefreshForAccessToken = ({ clientId, clientSecret, tokenEnd }; return fetch(tokenEndpoint, { headers: { - 'Content-Type': 'application/json' + 'Content-Type': 'application/x-www-form-urlencoded' }, method: 'POST', - body: JSON.stringify(payload) + body: new window.URLSearchParams(payload) }) .then(r => { if (!r.ok) { From 9142b40e2fcfdc08232aa12b4555d641010443f8 Mon Sep 17 00:00:00 2001 From: siya Date: Mon, 15 Jun 2020 19:51:28 +0200 Subject: [PATCH 7/7] clearing timer using useEffect --- src/lib/createAuthContext.js | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/lib/createAuthContext.js b/src/lib/createAuthContext.js index 525fe63..b0a8efc 100644 --- a/src/lib/createAuthContext.js +++ b/src/lib/createAuthContext.js @@ -41,21 +41,23 @@ export default ({ const useToken = () => { const { token, setToken } = useContext(context) - if (token) { - const now = new Date() - const elapsed = new Date(token.expires_at).getTime() - now.getTime() - const slack = elapsed + 10000 - console.log('djbfagkj') - if(token.refresh_token) { - setInterval(() =>exchangeRefreshForAccessToken({clientId, clientSecret, tokenEndpoint, fetch , token }) - .then(response => { - setToken(response) - }),slack - elapsed ) + useEffect(() => { + if (token) { + const now = new Date() + const elapsed = new Date(token.expires_at).getTime() - now.getTime() + const slack = 10000 + if(token.refresh_token) { + const timer = setTimeout(() =>exchangeRefreshForAccessToken({clientId, clientSecret, tokenEndpoint, fetch , token }) + .then(response => { + setToken(response) + }),elapsed - slack ) + return () => clearTimeout(timer) + } + } else { + console.warn(`Trying to useToken() while not being authenticated.\nMake sure to useToken() only inside of an component.`) } - return token - } else { - console.warn(`Trying to useToken() while not being authenticated.\nMake sure to useToken() only inside of an component.`) - } + },[token]) + return token }