question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Getting Refresh Token

See original GitHub issue

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.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:6
  • Comments:5

github_iconTop GitHub Comments

5reactions
colvintcommented, Sep 18, 2017

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)
  }
0reactions
TranHuuTrungcommented, Jun 27, 2019

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

Read more comments on GitHub >

github_iconTop Results From Across the Web

Get Refresh Tokens - Auth0
To get a refresh token , you must include the offline_access scope when you initiate an authentication request through the /authorize endpoint.
Read more >
Refresh Tokens - OAuth 2.0 Simplified
To use the refresh token, make a POST request to the service's token endpoint with grant_type=refresh_token , and include the refresh token as ......
Read more >
Get access and refresh tokens - Microsoft Advertising API
Access tokens are short lived, and you must refresh them after they expire to continue accessing resources. You can do so by submitting...
Read more >
Get an OAuth2 Refresh Token and Configure Your Client
Because OAuth2 access expires after a limited time, an OAuth2 refresh token is used to automatically renew OAuth2 access. Click the tab for...
Read more >
Get OAuth 2.0 access and refresh tokens - HubSpot API
Use the code you get after a user authorizes your app to get an access token and refresh token. The access token will...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found