auth0.js: Nonce does not match

I am getting an invalid_token: Nonce does not match. error from auth0.js when using the official example from here

The script:

webAuth.renewAuth({
  scope: 'openid',
  redirectUri: 'http://localhost:3000/silent-callback.html'
}

The silent callback:

<!DOCTYPE html>
<html>
  <head>
    <script src="https://cdn.auth0.com/js/auth0/8.6.1/auth0.min.js"></script>
    <script type="text/javascript">
      var webAuth = new auth0.WebAuth({
        domain: '****',
        clientID: '****'
      });
      var result = webAuth.parseHash(window.location.hash, function(err, data) {
        parent.postMessage(err || data, "http://localhost:3000");
      });
    </script>
  </head>
  <body></body>
</html>

It works if I use the usePostMessage option, which I cannot use because of #428

I am using Auth0.js 8.6.1 on latest Chrome.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 19 (8 by maintainers)

Most upvoted comments

As per dorilla’s comment above, we need to pass a random string to ‘solve’ the same problem of nonce errors. Not super happy with this workaround to be honest, mainly because I can’t explain it. Can anyone shed some light on why we need to do this?

auth.js

export default class Auth extends EventEmitter {
  auth0 = new auth0.WebAuth({
    domain: 'QQQ.eu.auth0.com',
    clientID: 'QQQ',
    redirectUri: `${window.location.origin}/auth/callback`,
    audience: 'https://QQQ.eu.auth0.com/userinfo',
    responseType: 'token id_token',
    scope: 'openid profile'
  });

  // etc...

  isAuthenticated() {
    // Check whether the current time is past the
    // access token's expiry time
    const expiresAt = JSON.parse(localStorage.getItem('expires_at'));
    if ( new Date().getTime() < expiresAt ) return true
    // Their token has expired, if they had one...
    const aTokenExists = JSON.parse(localStorage.getItem('access_token'))
    if ( aTokenExists ) return this.renew()
    // otherwise they've either logged out or never logged in
    return false
  }

  renew() {
    this.auth0.renewAuth({
      redirectUri: `${window.location.origin}/auth/renew`,
      usePostMessage: true,
      nonce: 'a random string to workaround auth0 bug', // https://github.com/auth0/auth0.js/issues/429
    }, (err, result) => {
      if (err) {
        this.login();
      } else {
        this.setSession(result);
      }
    });
  }
}

routes.js

export const makeMainRoutes = () => {
  return (
    <ApolloProvider client={client}>
      <BrowserRouter history={history}>
        <div>
          <Switch>
            <Route path="/auth/callback" render={(props) => {
              handleAuthentication(props);
              return <Callback {...props} />
            }}/>
            <Route path="/auth/renew" component={SilentCallback} />
            // etc...
          </Switch>
        </div>
      </BrowserRouter>
    </ApolloProvider>
  );
}

SilentCallback.js

export default function SilentCallback() {
  var data = {
    type: 'auth0:silent-authentication',
    hash: window.location.hash
  };
  window.parent.postMessage(data, "*");
  return null
}