I've tried adding prompt='consent', but I'm not seeing a refresh token returned in the response. I'm unclear on how to go about refreshing the id_token once the session has expired without forcing the user to continually re-login.
Same question here.
Does anyone find a way to get refresh_token?
Had the same issue with the JWT token expiring and logging the user out. I cooked up a scheme to detect JWT expiration and refresh it when it has expired. You can configure longer logged in durations by increasing MAX_JWT_REFRESHES:
<head>
<script src="https://apis.google.com/js/platform.js" async defer></script>
</head>
// in your app layout component or other component which is guaranteed to be available
export default class AppLayout extends Component {
componentDidMount() {
startJWTRefreshChecker()
}
render() {
// ...
}
}
import decode from 'jwt-decode'
import Promise from 'bluebird'
import AppConfig from 'config'
import { ID_TOKEN_KEY } from 'helpers/authHelper'
const MAX_JWT_REFRESHES = 10
const JWT_REFRESH_COUNT_KEY = 'jwt_refresh_count'
export const CHECK_JWT_REFRESH_TIMER_KEY = 'check_jwt_refresh_timer'
export function getJWTExpirationDate(token) {
const decoded = decode(token)
const date = new Date(0) // The 0 here is the key, which sets the date to the epoch
if(!decoded.exp) {
return null
}
date.setUTCSeconds(decoded.exp)
return date
}
export function checkJWTRefresh() {
const token = localStorage.getItem(ID_TOKEN_KEY)
console.log(`checkJWTRefresh...`)
if (!shouldRefreshJWT()) {
console.log('Maxed out JWT refreshes...')
return stopJWTRefreshChecker()
}
if (isJWTExpired(token)) {
refreshExpiredJWT()
}
}
export function shouldRefreshJWT() {
return getJWTRefreshCount() < MAX_JWT_REFRESHES
}
export function startJWTRefreshChecker() {
// start the refresh checker (checking once / sec)
return localStorage.setItem(CHECK_JWT_REFRESH_TIMER_KEY, setInterval(checkJWTRefresh, 1000))
}
export function stopJWTRefreshChecker() {
console.log('Disabling refresh check...')
return clearInterval(localStorage.getItem(CHECK_JWT_REFRESH_TIMER_KEY))
}
export function resetJWTRefreshCount() {
console.log('Resetting refresh count...')
return localStorage.setItem(JWT_REFRESH_COUNT_KEY, 0)
}
export function isJWTExpired(token) {
const date = getJWTExpirationDate(token)
if (date === null) {
return false
}
return !(date.valueOf() > new Date().valueOf())
}
export function refreshExpiredJWT() {
window.gapi.load('auth2', function () {
const existingAuthInstance = window.gapi.auth2.getAuthInstance()
let currentUserPromise
if (existingAuthInstance) {
currentUserPromise = Promise.resolve(existingAuthInstance.currentUser.get())
} else {
currentUserPromise = window.gapi.auth2.init({
client_id: AppConfig.googleClientId,
scope: AppConfig.googleClientScopes
}).then(function (res) {
return res.currentUser.get()
})
}
return currentUserPromise
.then((currentGoogleUser) => {
return currentGoogleUser.reloadAuthResponse()
})
.then(function (newAuthResponse) {
localStorage.setItem(ID_TOKEN_KEY, newAuthResponse.id_token)
localStorage.setItem(JWT_REFRESH_COUNT_KEY, getJWTRefreshCount() + 1)
console.log(`Refreshed expired JWT...`, getJWTRefreshCount() + 1)
})
})}
function getJWTRefreshCount() {
return parseInt((localStorage.getItem(JWT_REFRESH_COUNT_KEY) || '0'), 10)
}
I figured it out after lots of trial and error. You want to have the person authorize with responseType="code" on the client, then take the returned code and turn it into an access token and refresh token by using the call here on your server:
https://developers.google.com/identity/protocols/OAuth2WebServer#exchange-authorization-code
I have question like scandinaro commented. I get google reponse after login by email successfully and I call function reloadAuthResponse(), it is working properly , but I store them in redux and call again, it is not working! Give me a explain, please! Thanks
Most helpful comment
Had the same issue with the JWT token expiring and logging the user out. I cooked up a scheme to detect JWT expiration and refresh it when it has expired. You can configure longer logged in durations by increasing
MAX_JWT_REFRESHES: