There is a lot of information on the web about OAuth 2, its different types of flows and where/how to use them. I find that most of these resources discuss authenticating a user for an application, but I am struggling to understand what the best/correct approach would be when consuming third party APIs (i.e. when our own API is the "middleman" between a user and their data in a third party API).
With the help of an example scenario and some diagrams, I would be really grateful for advice/opinions on how I should properly implement integration with third party APIs and what the pros & cons of each approach are.
As a starting point, suppose we have a web app, structured as follows:
Now suppose that we wish to add integration with Google Sheets. The new feature would allow users to use their own Google Sheets (i.e. stored in their own Google account) as a data source, with the app having read&write access to the sheet. There may be other integrations in the future, so I am assuming that other APIs would require a similar process.
In addition to the existing OAuth process (which allows users to sign in to the "MyApp" frontend and communicate with the "MyApp API"), there needs to be an additional OAuth process for users to connect MyApp to the third party Google Sheets API.
The documentation has two Quickstart examples, but neither seems to quite fit my needs: Browser - https://developers.google.com/sheets/api/quickstart/js Node.js (console app) - https://developers.google.com/sheets/api/quickstart/nodejs
The data from the third-party (Google) API is one of potentially several integration points, so intuitively it seems more logical (and more secure) that all communication with the Google Sheets API should happen in the MyApp API
, and not on the frontend/client side. The MyApp API
would fetch data, process/manipulate/format it in some way and then present it for display in the frontend or mobile apps.
We require access to each user's own data, so the Client Credentials
flow is not suitable. I am focussing on the Implicit
or Authorization Grant
workflows.
Important note: The trickiness seems to come from the fact that the MyApp API
is stateless, so there is no long-lived session in which to store tokens. On that basis, it seems like tokens need to be stored either in the frontend (e.g. local storage/cookies etc) or in a backend database.
Below is my interpretation of two possible approaches. I'd appreciate thoughts/corrections.
Pros:
access_token
retrieved immediately without needing the code
stepCons:
Pros:
Cons:
Given that the data processing is to happen on the backend, option 2 seems slightly more suitable because the sensitive tokens can be hidden from the frontend app, and several clients (web frontend, mobile apps) have less obligation to be involved in the process with the exception of the initial sign in / user consent. However I’m not sure whether having a database full of user auth tokens is a good idea or how I could properly protect this database.
The good news is that both options are perfectly valid and equally secure. The concern about a short-lived Access Token being in the browser isn't an issue. Equally, if you only held the tokens on the BE, then you would need to implement your own client authentiation/session/JWT blah blah, which presents the same attack surface.
I've done both, and am currently migrating from BE to FE. In my case the reason is that everything I need to do, I can do on the FE, so I end up with no BE at all. This isn't strictly true since I do some onboarding/payment with the BE, but that's about all.
So the best approach depends on factors beyond those in your question, such as the nature of app, what the BE cost is and how important that is, what your devops skillsets look like for maintaining two environments, to what extent a BE is required anyway, vs being completely optional.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With