What is the best approach for storing OAuth2 tokens?

To be very honest I have not had to adjust any Wappler source files nor relink anything as such, I just used it as Wappler provides it, and it all just worked, the worst part was figuring out what the google API itself wanted by delving through their documentation.

So here is a brief outline of what I did.
After setting up all the stuff from Google Developer Console, which i know will be different for your usage, I then moved to Wappler.

  1. Created an index.php login page, with only one text input, not even in a form, and all it takes is the users gmail address. The reason I did this is for existing users already stored in my database, so they do not have to Authorise ever again. There is a button with an onclick event which points directly to my Server Action, so it looks a bit like this.
<div class="form-group">
	<input type="email" class="form-control" id="inputemaila" name="inputemaila" aria-describedby="inputemaila_help" placeholder="Enter Email Address to Authorise" required="" data-rule-email="">
</div>
<button class="btn btn-dark" dmx-on:click="browser1.goto('https://www.example.com/g-manager/dmxConnect/api/g-api-auth-a/token-handling-login.php?inputemaila='+inputemaila.value)">Get Authorised A</button>

The server action looks like this


The THEN condition
All this is doing is checking the database and if the email is in the database then it runs the API Action to use the refresh token from my database and get a refreshed access token. Then sends the newly refreshed access token to the "Self Maintain"provider, and updates the database with the new access token and the time it should expire. Lastly it redirects the user to my dashboard page.

The ELSE condition
If the user is not already in my database this runs, it uses the standard “Session” Provider and Authorize, then inserts the new user into the database with their Access Token, Refresh Token and expiry time of the token. Lastly it redirects the user to the same dashboard page.
NOTE: With the Google OAuth2 API the refresh token is only handed out once, so you have to capture this and store it, the only way to make Google give you a new one is by logging into your Google account and unauthorising the application manually. The same refresh token will then be used for this particular account forever.

Once I am at my dashboard page, i run a few steps on load, such as displaying some initial data like this


As you can see, there is no new Authorise step, just a single database query that fetches the email address, access token and refresh token.
I then put the Access Token and Refresh token inside their own Set Value steps, which is not something you have to do, however it makes it easier as the “linked” OAuth2 Provider can not have different inputs each time for the Access and Refresh Tokens, so this just makes it that I can keep the naming consistent.
Then I run the Provider with the details from the database like this

Then I run an API Action to get whatever data I want, in my case it initially just displays some of the users profile data so I have

Note: that in many cases the Define API Schema is not easily fetched on auto so I often times need to click my server action and click run in browser, which then outputs the json data, which i then copy from the browser window.
Here is what the output looks like for the API Action in the screenshot above

{"queryEmailA":{"tok_email":"example@gmail.com","tok_access_token":"ya29.a0*****WDg","tok_refresh_token":"1\/\/******dFEuNE"},"apiGetProfileA":{"status":200,"headers":{"0":"HTTP\/2 200","expires":"Sat, 09 May 2020 11:24:46 GMT","date":"Sat, 09 May 2020 11:24:46 GMT","cache-control":"private, max-age=0, must-revalidate, no-transform","etag":"\"hicYA7eHlM******Z45M\"","vary":["Origin","X-Origin"],"content-type":"application\/json; charset=UTF-8","content-encoding":"gzip","x-content-type-options":"nosniff","x-frame-options":"SAMEORIGIN","content-security-policy":"frame-ancestors 'self'","x-xss-protection":"1; mode=block","content-length":"116","server":"GSE","alt-svc":"h3-27=\":443\"; ma=2592000,h3-25=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q049=\":443\"; ma=2592000,h3-Q048=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""},"data":{"emailAddress":"example@gmail.com","messagesTotal":17098,"threadsTotal":16023,"historyId":"3076859"}}}

I then just copy the data part
{"emailAddress":"example@gmail.com","messagesTotal":17098,"threadsTotal":16023,"historyId":"3076859"}
out and manually paste it into my Define API Schema popup like this.

And thats pretty much the entire process.

A few things to note was obviously for Google Developer Console I needed to add the authorised URL that will be making these calls which in my case was
https://www.example.com/g-manager/dmxConnect/api/g-api-auth-a/token-handling-login.php As that is the only script that calls the entire brand new user app authentication script, i.e. the one that fetches the refresh token for me.

I hope this helps and does not make it even more confusing.

4 Likes