Multiple oAuth access and refresh tokens for single app on multiple machines

A breakdown of the project is that we have multiple computers running an offline application that only makes single API calls to Square via terminals.

We need to store the Access and refresh tokens locally for security reasons. However, whenever we do a token refresh, the server that doesn’t execute the oAuth refresh has no idea when the other one did, so then the access tokens would be different between them.

Is there a way for a client to have 2 separate tokens? Otherwise, I am thinking that they will need to be stored in some shared storage, but I doubt the client has that functionality setup on their end and I do not think it would be a good idea to store it on an external DB using API calls to get it.

If we cannot set 2 separate tokens, is there any other thoughts on how this could work?

:wave: Having two access tokens for one authorization isn’t currently supported. Have you reviewed our Best Practices for storing and managing credentials?

OAuth access tokens, refresh tokens, and the application secret all have privileged access (or the potential to get privileged access) to seller resources. You should use them in a secure environment and protect access to them using the following best practices:

  • OAuth operations should be performed on a secure application server. This includes, for example, calls to ObtainToken to obtain the original OAuth access token and refresh token, subsequent calls to get a new OAuth access token using a refresh token, generating and validating the state parameter, encrypting the tokens and application secret, and revoking a token. Do not store or use OAuth access tokens or refresh tokens on web or mobile clients.
  • OAuth access tokens and refresh tokens should be encrypted and stored in a secure database. Your application should use a strong encryption standard such as AES. The production encryption keys should not be accessible to database administrators, business analysts, developers, or anyone who does not need them. The tokens that these keys protect can be used to perform actions on behalf of the seller and should be guarded appropriately. The encryption keys should not be stored in source control and should only be accessible by server administrators.

Warning

Never store your credentials or access tokens in your version control system. The .env file is included in the .gitignore project to help prevent uploading confidential information.

You should never put the application secret in your source code. Instead, encrypt the secret and use an environment variable to reference the secret in your application. :slightly_smiling_face:

1 Like

Thanks for the update.

However, these applications are in Unity so they are not connected to a webserver. They each have their own database, where the tokens are stored with encryption, but the computer can only reference the token stored in its own database. Processing is done by connecting to the API using the UW tools provided in Unity. We also do a refresh token every 6 days after app restart at night.

However, I found that the old token still worked after the refresh was triggered. So both the new and old access tokens appear to be working.

When a token is refreshed, is the old one not revoked? If so, then we don’t have an issue on our end anymore. I assume that they will all revoke after the 30 day period, still, which isn’t a problem since each app will auto-update their tokens before then.

The only other solve would be to save the tokens on an external API server, but I don’t like the security risk involved with that…and we didn’t budget setting up an API

Currently, when a token is refreshed the old token will work until it expires or it’s revoked. :slightly_smiling_face:

I am not sure why you need multiple OAuth at all.

OAuth is for ‘each’ merchant (Seller) with each ‘location’.

There is one location with 2 computers running the application. They are kiosks where multiple people can make purchases at the same time.

You (your applicaton) must be able to update ‘merchant’s access token’ on or before 7 days using ‘refreshToken,’ which does not change. (your application must find a solution for automatically refreshing merchants’ token, seamlessly.)

Technically we have 30 days, but we we auto update in 5-6 based on the refresh token.

You are using database for your project, then why don’t you ‘encrypt merchants’ token and save it to the database rather than saving it locally? If you have to save ‘locally’ then why don’t you make your application (merchant’s end product) to access your ‘local database?’

We do. The databases are local to the computer. We do not have access to an internal shared database due to client restrictions. So, each computer runs its own application with its own terminal with its own encrypted tokens in the database.

There will be no problem storing access token as long as it is encrypted. Can you decrypt access token without any decrypting tool you are using?

No issues here. We already encrypt and decrypt inside the Unity app.

You should find a way to access ‘Unity’. I used to develop ‘Unity.’ Based on my experience with ‘Unity project,’ there are nothing impossible as your post.

I don’t think there is, but we are working with a non-technical client that can’t manually update their own tokens. Once I am done with the project, I am out of the process. I need to make this as easy as possible for them. We are already auto-refreshing the client tokens every 6 days based on refresh token. We also have an external token creation server if they need to manually updates as well. However, like I said, there is no shared database. Each computer and each application has its own.

That means that Computer 1 will see that the token hasn’t been updated in 6 days, so it will update and the access_token will now be “new”. The only times the Unity application makes a request is on startup (tokens, and it is restarted every morning) and when a checkout is made. However, Computer 2 will have a different date to read from and not update the token until needed. But my original concern was that if the token is revoked, how does the Computer 1 database know that it has been done if Computer 2 did it (different databases), or vice versa? They have different dates set and will refresh the token at different times, so there would be 2 access tokens instead of 1.

The basic fix is a shared database or internal API. I don’t want to build out a separate external DB with API to check against because:

  1. It is out of scope
  2. It is not secure enough. They were already freaking out that we had to make API requests to Sqaure.

I see you edited your comment, so I will respond to the new one as well.

Using online database or cloud for handling data (including webhook) is great plus for your project.

The client is not agreeing to this. It is not an option.

Understanding the nature of OAuth and refreshing ‘each’ merchant’s token on Square is must.

I do understand. Have built oAuth2 APIs in the past, but it was all for web. When it is not a web connected application, it gets a bit more complicated. At least in the concern that it is a first for me. I have done Unity development, I have done web development, but not with this. I do think we are going to need a webserver at some point, but due to client concerns currently, they said no.

I may can send you pseudocode for this issue but not the actual lines of coding.

I am good, but thank you. If I need extra assistance, I will contact you. Pseudocode is fine with me.

There is no reason to save each merchant’s access token (or refresh token) to your local DB at all.

There is only 1 merchant and will only be one merchant. They just have multiple terminals in a single location, with no webserver. Oh, and I think we are confusing ourselves. We are building the client application alongside the actual application, so I have full access to their account while we get it running. I am doing a mix of both setting up the code and setting it up for them. I am literally building their application on their computers through VPN. And since it is all localized, only their computers will store the keys for the apps.

If you have to, you can. Then every time your application from your merchant’s call to refresh merchant’s access token must be able to access your ‘local’ database (which does not make any sense at all). ======> this is your application’s problem.

I am not sure I follow. I can set info as .env variables, but I prefer to keep encrypted. The DBs are only hit on app startup. Really, no loss there. Once the date is hit, it passes in the data to the app, where it is stored until reboot.

Edit: I think you think that my app is being hit by theirs. It is all an internal thing, so the app its literally built into their system. This is not a webapp, it is an executable on each individual computer.

Make sure your application can access your online database to ‘refresh’ merchants access token on request.

Again an online DB is not an option. We had to convince them to install network cards on their PC’s just so they could interact with the Square API from the terminals.

Winner winner, chicken dinner.

Don’t ever remove this “feature”…haha

Now your application updated ‘merchants’ access token seamless’.
Then later, your merchant must use ‘updated merchant access token’ to access Saure.

However, your application must update your ‘merchant’s’ — not your Square Application’s’ — access token.

I know this. But the “application” is on my client’s machines as executables. So the merchant's different machines will have different tokens. However, I learned that old tokens aren’t revoked until the 30 days have passed, so it really isn’t an issue.

This database must update ‘each merchants’ access token which is refreshed’ regardless your local database or online (or clould) for later use for ‘merchant’, not your application.

Again, because it is a local executable, we are developing the application for the client themselves. There really is no external application since they are localized. This is not meant to work on other systems. It is a very outlier issue.

By the way,

You wrote,

Winner winner, chicken dinner.

Don’t ever remove this “feature”…haha

What is this?

There will be no more response on this thread if you think this issue as ‘chicken dinner.’

Thanks,

No. This is all built in the merchant application. We only access it from a dev account to manage code in the future.

I was responding to the Square employee who answered my question. Not sure if the reply was done on the wrong thread.

Basically at this point, access tokens are not revoked when a new token is acquired through the refresh_token. So my current implementation works fine.

Great to see that ‘So my current implementation works fine.’
And I have no reason to respond on 'Winner winner, chicken dinner.

Thanks,

I should just translate from Australian here. “Winner winner chicken dinner” is an Australian expression that means something like “I’m so happy to hear that! I feel like a winner now!”. There is no derogatory or negative component at all. I’m sorry, there’s no way you would understand that without explanation (or being telepathic!), and we Aussies just LOVE our slang and sometimes it’s understandably very confusing being on the receiving end!!

  • Brian