From 420ece73843558d1d3dd55ccdb25712335791191 Mon Sep 17 00:00:00 2001 From: Jason Hu Date: Fri, 13 Jul 2018 15:40:15 -0700 Subject: [PATCH] Check access token expires before we use it.If we found access token expires, we proactive call refresh token.So that we can avoid uncessary invalid auth error in backend. --- src/entrypoints/app.js | 9 ++++++++- src/entrypoints/core.js | 32 ++++++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/entrypoints/app.js b/src/entrypoints/app.js index 8f64cd4a4625..9f88cbc2406f 100644 --- a/src/entrypoints/app.js +++ b/src/entrypoints/app.js @@ -235,13 +235,20 @@ class HomeAssistant extends LocalizeMixin(PolymerElement) { const host = window.location.protocol + '//' + window.location.host; const auth = conn.options; try { + if (auth.accessToken && Date.now() > auth.expires) { + // Refresh acess token if we know it expires + const accessToken = await window.refreshToken(); + conn.options.accessToken = accessToken.access_token; + conn.options.expires = accessToken.expires; + } return await hassCallApi(host, auth, method, path, parameters); } catch (err) { if (!err || err.status_code !== 401 || !auth.accessToken) throw err; // If we connect with access token and get 401, refresh token and try again const accessToken = await window.refreshToken(); - conn.options.accessToken = accessToken; + conn.options.accessToken = accessToken.access_token; + conn.options.expires = accessToken.expires; return await hassCallApi(host, auth, method, path, parameters); } }, diff --git a/src/entrypoints/core.js b/src/entrypoints/core.js index 76647a943086..96734fa5d4ab 100644 --- a/src/entrypoints/core.js +++ b/src/entrypoints/core.js @@ -18,7 +18,8 @@ const init = window.createHassConnection = function (password, accessToken) { if (password) { options.authToken = password; } else if (accessToken) { - options.accessToken = accessToken; + options.accessToken = accessToken.access_token; + options.expires = accessToken.expires; } return createConnection(url, options) .then(function (conn) { @@ -39,12 +40,19 @@ function redirectLogin() { window.refreshToken = () => refreshToken_(clientId(), window.tokens.refresh_token).then((accessTokenResp) => { window.tokens.access_token = accessTokenResp.access_token; + // shorten access token life 30 seconds to cover network cost + window.tokens.expires = ((accessTokenResp.expires_in - 30) * 1000) + Date.now(); localStorage.tokens = JSON.stringify(window.tokens); - return accessTokenResp.access_token; + return { + access_token: accessTokenResp.access_token, + expires: window.tokens.expires + }; }, () => redirectLogin()); function resolveCode(code) { fetchToken(clientId(), code).then((tokens) => { + // shorten access token life 30 seconds to cover network cost + tokens.expires = ((tokens.expires_in - 30) * 1000) + Date.now(); localStorage.tokens = JSON.stringify(tokens); // Refresh the page and have tokens in place. document.location = location.pathname; @@ -66,11 +74,23 @@ function main() { } if (localStorage.tokens) { window.tokens = JSON.parse(localStorage.tokens); - window.hassConnection = init(null, window.tokens.access_token).catch((err) => { - if (err !== ERR_INVALID_AUTH) throw err; + if (window.tokens.expires === undefined) { + window.tokens.expires = Date.now() - 1; + } + if (Date.now() > window.tokens.expires) { + // refresh access token if we know it expires to reduce unncessary backend invalid auth event + window.hassConnection = window.refreshToken().then(accessToken => init(null, accessToken)); + } else { + const accessTokenObject = { + access_token: window.tokens.access_token, + expires: window.tokens.expires + }; + window.hassConnection = init(null, accessTokenObject).catch((err) => { + if (err !== ERR_INVALID_AUTH) throw err; - return window.refreshToken().then(accessToken => init(null, accessToken)); - }); + return window.refreshToken().then(accessToken => init(null, accessToken)); + }); + } return; } redirectLogin();