0

As I asked described here:

I am building a service where I have code borrowed from the SocialBootstrapApi. I am specfically using the Linkedin oauth2 provider though.

I have no complaints for a single user - the code works nicely, but if the same user logs in simultaneously from two differen machines (using the same linkedin account) the original logins access token is invalidated. While the user stays logged in (because session cookies are already in place) if the user performs an action that uses the expired access token to perform a task that requires a linkedin api call, the call fails with an invalid access token error. Obviously I understand the reason behinds this, but I am not sure how to rectify it. In this mobile first world, we have so many devices and one device can't logoff a user from another device.

So, should I re-get the access token from the UserAuthDetails table everytime before I perform an api call just in case it has been invalidated? Or, shouldn't this be updated in the cache and next time the access token is accessed, the refreshed one is served because the cache has been updated?

Thanks

t316
  • 1,149
  • 1
  • 15
  • 28

1 Answers1

0

The easiest option (and my preferred solution) is to just fetch the access tokens from the IAuthRepository before making the API call. IAuthRepository.GetUserAuthDetails() will return the UserAuthDetails that contains the access tokens.

This can be slightly optimized by first attempting to use the access tokens on the session before hitting the UserAuth backend datastore, although as it's likely the cost of the required simple db call to a internal datastore is going to be a lot less than the call to a remote service (i.e. LinkedIn API's) - the optimization may not be worth it. But if you're going with this approach I'd update the Users Session with the fresh access tokens so next time the fresh tokens from the cache can be used.

Each User Session references a different Session in the Cache

Users authenticating from different browsers, pc's, devices, etc are each given their own session which is just the AuthUserSession POCO's stored in the registered ICacheClient referenced by ServiceStack's Session Cookies, i.e. they don't share the same Cache so changes to one of the users session doesn't affect any other Users Sessions.

mythz
  • 141,670
  • 29
  • 246
  • 390
  • Just to follow-up on this. In a class modeled around the TwitterInGateway, what's the best way of getting the userAuthId to pass in to GetUserAuthDetails(string userAuthId) method? And does the GetOAuthTokens(providerName) accomplish the same thing? If it does then not keeping a private singleton ILinkedInGateway and dynamically recreating the Gateway on the getter everytime should probably fix this right in a similar manner to what you suggest, right? – t316 Nov 30 '14 at 15:10
  • [GetOAuthTokens](https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack/AuthUserSession.cs#L107) only looks at the Session. You can get the `UserAuthId` from `session.Id`. You'll either need to create a new instance of the Gateway with the users access tokens or pass the tokens as a parameter on each request. – mythz Nov 30 '14 at 15:23
  • Would I be updating the tokens in UserSession.ProviderOAuthAccess and then saving the session to propagate the oauth tokens through the session to the other sessions? Meaning once I save the session with updated tokens, the other session would get the updated tokens when I call UserSession.GetOAuthTokens? Sorry if I seem a little confused... – t316 Nov 30 '14 at 15:24
  • @t316 Changes to sessions doesn't affect any other session (as mentioned in the answer), so updating the Session only affects that specific Users session. All other Users sessions will need to refresh themselves in the same way. – mythz Nov 30 '14 at 15:31