Angular-oauth2-oidc: Silent refresh timing issue

Created on 9 Jan 2018  路  9Comments  路  Source: manfredsteyer/angular-oauth2-oidc

Hi,

Silent refresh timeout is calculated wrong if user does a page reload. calcTimeout() returns constant timeout when ever it is called. Shouldn't it take into account current time, not stored_at?

E.g. in Scenario:

  • Token expiration time is 1min
  • timeoutFactor 0.5
  • calcTimeout() returns 30000 (30sec) when user does a page reload, causing that app looses valid token, depending on the timing the page reload occurs.

Following change seems to work in our use case (+ changes to calling code). Is there some reason behind to use stored_at?

private calcTimeout(storedAt: number, expiration: number): number {
    let delta = (expiration - storedAt) * this.timeoutFactor;
    return delta;
}

=>
private calcTimeout(expiration: number): number {
let delta = (expiration - Date.now()) * this.timeoutFactor;
return delta;
}

Most helpful comment

I've had the same problem and created pull request #213

All 9 comments

I've had the same problem and created pull request #213

Why is this one closed? Timeout calculation is still wrong on the master branch. PR is not merged yet.

Thx for this. It should be correct, as it is implemented. The idea is to do a refresh aber x% of the overall token lifetime, hence it's using stored_at.

Also see: https://github.com/manfredsteyer/angular-oauth2-oidc/pull/213

The timeout calculation is still causing problem.

If I reload the page a few seconds before the token lifetime ends I'm still logged in but on REST cals I get an 401 (UNAUTHORIZED).

So there are two options.

  1. send logout event when token expires
  2. change timeout calculation to refresh token in time

We were having the exact same issue in our application.

It's easy to reproduce if you refresh the site while the silent refresh timeout is running. When the page reloaded it will start a new timer but with the same timeout as before (because storedAt and expiration have not changed). This causes the token to expire before the silent refresh renews the token.

Example:

Current time: 12:00:00
Token is stored at: 12:00:00
Token expires at: 12:01:00

calcTimeout returns: 45 seconds
Silent refresh will happen at: 12:00:45

--- Wait 20 seconds. Refresh the page ---

Current time: 12:00:20
Token is stored at: 12:00:00
Token expires at: 12:01:00

calcTimeout returns: 45 seconds <-- This is the error!
Silent refresh will happen at: 12:01:05 
but token already expired...

We manually overwrote the calcTimeout function with the implementation @gerkirill suggested in https://github.com/manfredsteyer/angular-oauth2-oidc/pull/213#issuecomment-373363958 which fixes the problem

We manually overwrote the calcTimeout function with the implementation @gerkirill suggested in #213 (comment) which fixes the problem

@joostme, can you please elaborate on how you managed to overwrote calcTimeout ?

@morvans

@joostme, can you please elaborate on how you managed to overwrote calcTimeout ?

In the Angular Service we first inject the OAuthService from 'angular-oauth2-oidc' we overwrite the calcTimeout function the following way:

(<any> this.oAuthService).calcTimeout = function (storedAt: number, expiration: number): number {
    const tokenLifetime = expiration - storedAt;
    const refreshTime = storedAt + (tokenLifetime * this.timeoutFactor);
    const timeLeft = Math.max(0, refreshTime - Date.now());
    return timeLeft;
};

@joostme :+1:
Thanks !

@joostme Thanks for the tip. I didn't know about this override ability.

@manfredsteyer This will really need to be somehow fixed and released.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kneefer picture kneefer  路  3Comments

Swissbite picture Swissbite  路  4Comments

jeroenheijmans picture jeroenheijmans  路  4Comments

phrouv picture phrouv  路  4Comments

zulander1 picture zulander1  路  4Comments