We store the bearerToken and refreshToken in local storage after a successful sign-in.
We populate the bearerToken and refreshToken on our JSONServiceClient and everything is working nicely.
I’m a little confused how we handle the scenario below and am looking for some guidance please…
When a 401 is experienced the JSONServiceClient handles the refresh of the token and on success updates it’s bearerToken.
How do JSONServiceClient consumers detect this refresh so that local storage can be updated to persist sessions on browser refreshes?
There’s no callback, just the BearerToken gets populated. Normally Apps send an empty /auth or Autenticate() request on first access to check if their Authenticated and retrieve their Authenticated info. So you can update the BearerToken after that. Although you don’t really need to persist the BearerToken as you only need the RefreshToken which will be used to retrieve a new BearerToken.
Note: When the RefreshToken Expires a RefreshTokenException will be thrown, which clients can use to redirect the the user to re-authenticate.
So, can I clarify something: after the app reloads and we send an /auth request, on a successful response, do we need to set the bearerToken ourselves or does the JSONServiceClient automatically set it for us?
The RefreshToken only gets auto populated when using the default JWT Token Cookies where after successful Authentication, the client will be populated with Refresh & Bearer Tokens.
Otherwise the JsonServiceClient needs to populate it after successful Authentication (or retrieved from local storage). If the JsonServiceClient auto refreshes the BearerToken it will populate it itself, which it does if no BearerToken is populated or it’s expired.
OK thanks, so it sounds like we don’t need to handle the bearerToken at all. Can you confirm if the following sounds correct…
The web app loads and whilst loading…
We load the refreshToken from localstorage and assign to the JSONServiceClient
We send an empty /auth request to see if the cookies will authenticate for us.
If successful, we write the refreshToken to localstorage and the bearerToken and refreshToken are automatically configured inside the JSONServiceClient, ie we don’t need to handle these tokens ourselves.
If failure, we check type of exception…
If RefreshTokenException we redirect to the sign-in page
Else, we log the exception
From then on the JSONServiceClient will handle expiry automatically and on a reload the above process will handle jwt retrieval
If you UseTokenCookies (i.e. default in v6+) then you would populate the RefreshToken Cookie with SetRefreshTokenCookie() to set the ss-reftok cookie, then you wouldn’t need to manually handle BearerTokens as re-authenticating will re-populate the Reresh & Bearer Tokens (in ss-reftok & ss-tok Cookies).
Its an angular app (sorry, should have said, just tagged with clients - typescript so thought that was enough) so we’re using the JsonServiceClient that comes in @servicestack/client
If it’s in the browser then it will use the browser cookies which will already be persisted across browser sessions.
Using JWT Cookies is the recommended solution for Ajax clients since they use Secure, HttpOnly cookies which aren’t accessible from JavaScript making them immune to XSS attacks, and why you never want to persist them in localStorage.
You shouldn’t need to do anything for SPAs, authenticate normally and let the cookies control the lifetime. Check /auth on Startup if they’re authenticated and authenticate them if not.