mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-22 16:56:35 +00:00
Check access token expires before we use it. (#1444)
* 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. * Move expires calc to fetchToken() and refresToken() * Address code review comment
This commit is contained in:
parent
b5ff52febf
commit
348b284ba6
@ -8,6 +8,8 @@ export default function fetchToken(clientId, code) {
|
|||||||
body: data,
|
body: data,
|
||||||
}).then((resp) => {
|
}).then((resp) => {
|
||||||
if (!resp.ok) throw new Error('Unable to fetch tokens');
|
if (!resp.ok) throw new Error('Unable to fetch tokens');
|
||||||
return resp.json();
|
const tokens = resp.json();
|
||||||
|
tokens.expires = (tokens.expires_in * 1000) + Date.now();
|
||||||
|
return tokens;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,8 @@ export default function refreshAccessToken(clientId, refreshToken) {
|
|||||||
body: data,
|
body: data,
|
||||||
}).then((resp) => {
|
}).then((resp) => {
|
||||||
if (!resp.ok) throw new Error('Unable to fetch tokens');
|
if (!resp.ok) throw new Error('Unable to fetch tokens');
|
||||||
return resp.json();
|
const tokens = resp.json();
|
||||||
|
tokens.expires = (tokens.expires_in * 1000) + Date.now();
|
||||||
|
return tokens;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -235,13 +235,20 @@ class HomeAssistant extends LocalizeMixin(PolymerElement) {
|
|||||||
const host = window.location.protocol + '//' + window.location.host;
|
const host = window.location.protocol + '//' + window.location.host;
|
||||||
const auth = conn.options;
|
const auth = conn.options;
|
||||||
try {
|
try {
|
||||||
|
// Refresh token if it will expire in 30 seconds
|
||||||
|
if (auth.accessToken && Date.now() + 30000 > auth.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);
|
return await hassCallApi(host, auth, method, path, parameters);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (!err || err.status_code !== 401 || !auth.accessToken) throw 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
|
// If we connect with access token and get 401, refresh token and try again
|
||||||
const accessToken = await window.refreshToken();
|
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);
|
return await hassCallApi(host, auth, method, path, parameters);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -18,7 +18,8 @@ const init = window.createHassConnection = function (password, accessToken) {
|
|||||||
if (password) {
|
if (password) {
|
||||||
options.authToken = password;
|
options.authToken = password;
|
||||||
} else if (accessToken) {
|
} else if (accessToken) {
|
||||||
options.accessToken = accessToken;
|
options.accessToken = accessToken.access_token;
|
||||||
|
options.expires = accessToken.expires;
|
||||||
}
|
}
|
||||||
return createConnection(url, options)
|
return createConnection(url, options)
|
||||||
.then(function (conn) {
|
.then(function (conn) {
|
||||||
@ -40,7 +41,10 @@ window.refreshToken = () =>
|
|||||||
refreshToken_(clientId(), window.tokens.refresh_token).then((accessTokenResp) => {
|
refreshToken_(clientId(), window.tokens.refresh_token).then((accessTokenResp) => {
|
||||||
window.tokens.access_token = accessTokenResp.access_token;
|
window.tokens.access_token = accessTokenResp.access_token;
|
||||||
localStorage.tokens = JSON.stringify(window.tokens);
|
localStorage.tokens = JSON.stringify(window.tokens);
|
||||||
return accessTokenResp.access_token;
|
return {
|
||||||
|
access_token: accessTokenResp.access_token,
|
||||||
|
expires: window.tokens.expires
|
||||||
|
};
|
||||||
}, () => redirectLogin());
|
}, () => redirectLogin());
|
||||||
|
|
||||||
function resolveCode(code) {
|
function resolveCode(code) {
|
||||||
@ -66,11 +70,24 @@ function main() {
|
|||||||
}
|
}
|
||||||
if (localStorage.tokens) {
|
if (localStorage.tokens) {
|
||||||
window.tokens = JSON.parse(localStorage.tokens);
|
window.tokens = JSON.parse(localStorage.tokens);
|
||||||
window.hassConnection = init(null, window.tokens.access_token).catch((err) => {
|
if (window.tokens.expires === undefined) {
|
||||||
|
// for those tokens got from previous version
|
||||||
|
window.tokens.expires = Date.now() - 1;
|
||||||
|
}
|
||||||
|
if (Date.now() + 30000 > window.tokens.expires) {
|
||||||
|
// refresh access token if it will expire in 30 seconds to avoid 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;
|
if (err !== ERR_INVALID_AUTH) throw err;
|
||||||
|
|
||||||
return window.refreshToken().then(accessToken => init(null, accessToken));
|
return window.refreshToken().then(accessToken => init(null, accessToken));
|
||||||
});
|
});
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
redirectLogin();
|
redirectLogin();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user