Refresh token invalid after first try (solid-node-client)

Hello! I am trying to test my solid application and came across the following problem.
I get the credentials successfully with generate-oidc-token, and use them with solid-node-client to connect to the pod in my test.
It works just fine the first time, but if I rerun the test it throws invalid refreshToken.

Any ideas?

Invalid refresh credentials: OPError: invalid_grant (Invalid refresh_token)

  at refreshAccess (node_modules/@inrupt/solid-client-authn-node/src/login/oidc/oidcHandlers/RefreshTokenOidcHandler.ts:105:11)
  at RefreshTokenOidcHandler.handle (node_modules/@inrupt/solid-client-authn-node/src/login/oidc/oidcHandlers/RefreshTokenOidcHandler.ts:150:24)
  at ClientAuthentication.login (node_modules/@inrupt/solid-client-authn-node/src/ClientAuthentication.ts:60:25)

Test code:


Thanks for reporting. I can reproduce. Looks like a problem with either the server or one of the downstream libraries. I’ve filed this bug, you may want to add further details there : Login failure with authn-node · Issue #1285 · inrupt/solid-client-authn-js · GitHub

Hi ! I replied to the Github issue @jeffz kindly opened providing some details about the issue, but there is a workaround that may be simpler than the “cleaner” proposed solution. The workaround doesn’t exactly resolve the issue per se, but it yields the expected behaviour nonetheless (I think).

The core issue here is that the ESS Solid Identity Provider implements a process called refresh token rotation, which means that each refresh token is only valid once, and when used it is replaced by a new refresh token. This is considered a good practice from a security perspective, but I can see how it can be perceived as more cumbersome from the user point of view. One thing to note is that NSS does not implement this, and still follow the previous behaviour of having a single refresh token that you can use over and over again.

Therefore, one thing you can do is to use NSS as your Identity Provider. You can use @inrupt/generate-oidc-token to get a token with an NSS instance as your OIDC issuer (e.g. This token will be associated to a WebID, e.g. If this WebID has the appropriate access permissions set for the data hosted on an ESS Pod, you can log your script in with the refresh token, and issue authenticated requests to the ESS Pod where the data is stored.

Could this approach be used to resolve your issue ?

1 Like

Yep, it works perfectly for my testing needs. Never thought of that clever workaround.

Thank you so much!