Do you have a sample where there is a JWT Auth (with refresh token)? That would be great!
The refreshToken is the same for all Service Client examples, I.e it’s returned in AuthenticateResponse DTO when you Authenticate which you can then assign to the ‘refreshToken’ property of the Service Client, e.g:
Thanks for the links; the special thing was more how to define the Service Client in order to get the state after refresh; would it be a good idea to put the instance of the JsonServiceClient (with the refreshToken as a property) in the store.js and keep de refreshToken in LocalStorage (or will the cookie pick it up?).
Update: I did the test with setting the client.refreshToken = response.refreshToken;
after the authentication; set the expiry of the token to 30 seconds; and after 1 minute I was still be able to get a secured call.
However, when I restart my server, the authenticated user is not known anymore; I think this is because the session is persisted in memory on the server; but then again, the bearer-token and refresh-token are they to stay authenticated even when the server is reset… not?
Is there a way to save the bearer-token and refresh-token and let the jsonserviceclient pick them up from a cookie or localstorage?
Update 2: Learning The Caching on the server works (if persisted), but not a fan of it (why is the Expiry date for the sessionID much larger than the Token?).
What I did now, seems to work, but not sure, best way to do:
const request = new Authenticate();
request.userName = userName;
request.password = password;
request.provider = 'Credentials';
request.UseTokenCookie = true;
I now added the UseTokenCookie
(not sure if needed). But I also had to add
var response = await client.post(request);
client.refreshToken = response.refreshToken;
localStorage.setItem('refreshtoken', response.refreshToken);
and on all subsequent calls:
const request = new SecureCall();
request.name = name;
client.refreshToken = localStorage.getItem('refreshtoken');
var result = await client.get(request);
I am adding the refresh token again.
Is this the way to do it?
… hmm … this does not work when I refresh/restart server, the first call (because the bearer token itself is not set). Is there a hook where, once the client
gets a new bearer-token, it is also stored in localstorage?
What does your JWT Provider registration look like? Are you using the same key between restarts?
Yes certainly. It is working in regular c# apps or xamarin. After reading through docs again the UseCookieToken should do what I need without server caching. Could it be that it already had a sessiin cookie as well?
I’d need to see the HTTP Headers to be able to confirm what’s actually happening.
You shouldn’t just be using the refreshToken
for all calls as that forces an extra call to fetch the bearerToken per API Request. Once the client
fetches the bearerToken
the first time it populates it on the client
instance which it the sends for subsequent requests until it fails. You’ll also want to use the same client
instance for all requests to the same server.
Yes the bearerToken
and refreshToken
are stateless and will survive app restarts as long as the JwtAuthProvider
is configured to use the same key.
If you use UseTokenCookie=true
when you Authenticate
ServiceStack removes the UserSession from the ICacheClient
and returns the JWT in the ss-tok
HttpOnly Cookie. For the requests that fail you should check that the ss-tok
is being sent, if it is than it’s likely that your JWT has expired.
Note this is the same behavior if you call ConvertSessionToToken
after authenticating:
await client.post(new ConvertSessionToToken());
Where it will convert the existing server session into a JWT and return it in the ss-tok
Cookie.
Please take a look at:
https://github.com/stefandevo/vue-nuxt
I have added JWT authentication, added a login button, and secured the hello service (removed all the other services from the site).
This now seems to work as expected, but please check:
https://github.com/stefandevo/vue-nuxt/blob/master/MyApp/src/shared/gateway.js
I add the refresh-token to localStorage, because otherwise, when refreshing or starting a new tab, the refreshtoken is unknown and a 401 appears. I have no session memory on the server with this, making the implementation possible for server-farms.
But is this the way it should work? Or do you have any suggestions?
If you refresh the page you will lose any of the existing JS state (i.e. incl. the client
instance), so you would need to re-login again in order to fetch a new refreshToken
or you could persist the token in localStorage and rehydrate it on startup as you’re doing.
So basically, the approach used, is a good approach do you think?
The idea would be that the user can close the browser, and still keeps logged in into the system next time he starts the app (until Logout).
Yeah if you want to save the user from logging in again, saving the JWT or RefreshToken in localStorage
is the best option.