Authenticating with OAuth 2.0
The OAuth 2.0 Dance - The Authorization Code way
There are so many resources on the internet that explain how to properly do the dance. If you've ever tried to learn the newest viral TikTok dances or even the most basic line dance in your high school gym, you know quite well, they still take lots of practice.
I won't try and reinvent the wheel, but what I will try to do is provide context on how to properly authenticate a FreshBooks user to your app. Who knows, maybe your new app will go viral (that sounds negative in this context...)
We'll start off this tutorial with an expectation that you have a FreshBooks account (trial or paid), a basic understanding of what OAuth is and why you need to use it. To be explicit, we are going to be using the Authorization Code Grant flow of OAuth 2.0
From a human's perspective, this is what's going to happen. Someone on the internet (a user) wants to use the app you've created. In order to do so, they will need to provide your app with permission to make requests on its behalf and read and write information to your account.
To do so, you will give them an Authorization URL (that FreshBooks generates). This will link them to a custom Authorization page that FreshBooks hosts with the Client ID of your app associated with it. FreshBooks will ask the user to enter in their FreshBooks credentials in order to give you access to connect your app to their account.
Once the user logs in and clicks "Authorize Access", the authorization server will redirect the user back to your page/app (using the Redirect URI you entered in the App creation) with the user's code attached to it.
Since you own that site, you can query the request parameters, take the code of the user (which is always changing depending on the user), attach the Client ID and Client Secret of the app and redirect URI (all static and unchanging in your app) and exchange it for an Access Token and Refresh Token in FreshBooks.
Your app can now use the Access Token and Account ID to identify the user and prove you have been given permission make changes on the user's behalf. Keep in mind that every 12 hours that Access Token expires, so you can use your Refresh Token (which never expires, but can only be used once) to get a new Access Token and keep going.
Once you get an Access Token and Refresh Token you should never technically need to reauthenticate the user and go through that entire flow again. (But naturally, there are a kabillion reasons why one might).
Now that we know the general overview, let's get into the technical aspect of it.
First off you'll need to create an app. You can do this by going to my.freshbooks.com/#/developer or you can login to your FreshBooks account.
- Click on the Settings gear in the top left-hand corner
- Choose the Developer Portal tab
- Now click on Create an App in the top right-hand side of the screen.
NOTE: It's important you add full URLs, including the
https://prefix. It's also important that if you are building a scalable app that you have a
redirect_urithat you own because you want to be able to query the URL associated with that redirect.
Once this is created, you will be given an Authorization link in the App Management page.
A user visits your Authorization link, which you supply on your website.
You can find this link on your App Management page. Feel free to add this link anywhere you like; we can also put it on our marketplace!
They are sent to an Authorization page we host. If the user is not logged in, they will be asked to and then sent to the below page. If the user is already logged in, they will go directly to this page.
Note: your app's name, scope and info will show on this page.
The user logs in and clicks 'Authorize' to authorize your app.
They are redirected back to your website with a code parameter in the URL.
You consume that code and send us a request from your server containing the code, your
client_secret, and the
redirect_urithe user followed.
On line 17, I'm going to show you what that code looks like:
On line 18 we take that
codeand add it to our bearer function.
You can then make the the request for an
access_token, you will also need to add
redirect_uri(they must match).
NOTE: It is only the
codethat is going to change on a user-by-user basis, everything else will remain static.
We return to you an
- NOTE: It's important you encrypt these and store them safely in a database. There are plenty of libraries that can help you with this.
Your app can now make successful calls on that user's behalf.
refresh_tokencan only be used once. Your
access_tokenwill expire every 12 hours or so. You can use your
refresh_tokento get a new
access_tokenexpires, but you need to change the code type from
refresh_tokenas seen here.
For a list of additional great resources on how to do this more generally, you can go here: Okta: https://developer.okta.com/blog/2018/04/10/oauth-authorization-code-grant-type
OAuth Grant Types:https://oauth.net/2/grant-types/
Why access_tokens are short lived and refresh_tokens are not: https://www.oauth.com/oauth2-servers/access-tokens/access-token-lifetime/
Another Great Resource for Authentication Code Flow: https://medium.com/@darutk/diagrams-and-movies-of-all-the-oauth-2-0-flows-194f3c3ade85