As part of our “Building Smarter with Intuit” series around best practices for developing applications with Intuit APIs, we’re sharing insights and tips on optimizing everything from authorization to advanced platform capabilities. Stay tuned for more articles in this series designed to help you level up your app development on the Intuit developer platform.
So, what is OAuth?
OAuth 2.0 (or OAuth2 for short) is an industry-standard authorization framework that provides a secure way for a third-party application to access resources on behalf of a user. It does so without requiring the user to provide their credentials directly to the third-party application.
A standard OAuth flow looks like this:
- The third-party application initiates a request to access a resource on a server.
- The server responds with a redirect to the authorization server.
- The user authenticates with the authorization server and grants permission to the third-party application to access the requested resource.
- The authorization server generates an access token and sends it to the third-party application.
- The third-party application uses the access token to access the requested resource on behalf of the user.
- The server validates the access token and grants access to the requested resource.
Overall, OAuth2 provides a secure and standardized way for third-party applications to access resources on behalf of users without the risk of compromising their credentials.
Now that we have a conceptual understanding of OAuth, this is how it works with the Intuit Developer platform:
- Register your application with Intuit Developer:
- Go to the Intuit Developer website and create an account.
- Once you have an account, you can register your application with Intuit.
- Create a new application and choose the relevant API scopes.
- Fill in the required information, such as the application name and redirect URI.
- Obtain client credentials:
- After registering your application, you will receive a client ID and client secret.
- These credentials will be used to authenticate your application with Intuit’s OAuth server.
- Configure your application:
- Once your application is registered with Intuit Developer, you will need to configure it with the appropriate settings. This includes setting up the authorization URL, token URL, environment, etc.
- Once your application is configured, you can begin implementing the authorization flow.
- Implement the authorization flow:
- Your application will need to implement the authorization flow to obtain an access token from Intuit.
- This involves first redirecting the user to Intuit’s authorization endpoint, where they will be prompted to grant access to your application.
- Once the user grants access, Intuit will redirect them back to your application (based on the redirect URI you registered earlier) with an authorization code and corresponding realmID (unique ID for the QuickBooks Online customer).
- You then exchange the authorization code for an access/refresh token using Intuit’s token endpoint.
- These tokens should be persisted alongside the realmID in a secrets manager.
- Use the access token:
- Once your application has obtained an access token, it can use this token to make Intuit API requests on behalf of the user. This includes making requests for user data, creating transactions, and more.
- Include the access token in the Authorization header of your API requests. For example,
Authorization: Bearer <accces_token>
- Handle token expiration and refresh:
- Access tokens have a limited lifespan and will eventually expire.
- Using the refresh token, call the token endpoint to receive a fresh set of tokens.
How do I implement OAuth2 in Node.js?
Ready to pull up your sleeves and implement OAuth? This next section will focus on implementing OAuth in Node. To help you on this journey, Intuit provides a Node.js OAuth client library. We’ll make heavy use of this library for this tutorial. It’s assumed you already have an existing web app that you want to integrate with QuickBooks Online. If you haven’t done so already, you’ll want to follow these steps to create an application on the Intuit Developer portal.
First, register your application with the Intuit Developer portal by going to the Intuit Developer website and creating an account. Once you have an account, you can register your application with Intuit. When you create a new application, OAuth 2.0 is the default authentication method. Fill in the required information in your application, such as the application name, redirect URI, and scopes.
After registering your application, you will receive a client ID and client secret. These credentials will be used to authenticate your application with Intuit.
Once your application is registered, you will then need to configure it with the appropriate settings. This includes setting up the authorization URL, token URL, and other settings.
Next, download the Intuit Node.js OAuth client Lib or clone the repo from GitHub.
Note: It is assumed that you have already installed npm and nodejs.
1. Run the installation steps from a terminal window:
cd \oauth-jsclient\sample
npm install
cp .env.example .env
2. Start the client application:
npm start
3. Then, follow these steps to start the oAuth client UI:
- Step 1: Paste this URL in your browser: http://localhost:8000
- Step 2: Copy and Paste the clientId and clientSecret from: https://developer.intuit.com
- Step 3: Copy and Paste this callback URL into `redirectURI`: http://localhost:8000/callback
- Step 4: Make Sure this redirect URI is also listed under the Redirect URIs on your app in: https://developer.intuit.com
4. You should be able to click “Connect to QuickBooks” to get access tokens and make a sample API call.
5. To unfold the contents of your Node.js client application, open the app.js file and make sure you have imported the necessary libraries:
require('dotenv').config();
const express = require('express');
const app = express();
const path = require('path');
const OAuthClient = require('intuit-oauth');
const bodyParser = require('body-parser');
const ngrok = process.env.NGROK_ENABLED === 'true' ? require('ngrok') : null;
6. Now, let’s get your request query json object populated with required input values and create an OAuth2 client.
let oauthClient = null;
app.get('/authUri', urlencodedParser, function (req, res) {
oauthClient = new OAuthClient({
clientId: req.query.json.clientId, /* ‘<your_app_client_id>’ */
clientSecret: req.query.json.clientSecret, /* ‘<your_app_client_secret>’ */
environment: req.query.json.environment, /* ‘Sandbox’ */
redirectUri: req.query.json.redirectUri, /* ‘http://localhost:8000/callback’ */
});
7. Next, get the authorization URI, and redirect the user to Intuit’s authorization endpoint, where they will be prompted to grant access to your application.
const authUri = oauthClient.authorizeUri({
scope: 'com.intuit.quickbooks.accounting',
state: 'intuit-test',
});
res.send(authUri);
});
8. Once the user grants access, Intuit will redirect them back to your application with an authorization code. The next thing you’ll need to do is to handle the callback to extract the `Auth Code` and exchange them for access tokens (aka `Bearer-Tokens`).
app.get('/callback', function (req, res) {
oauthClient
.createToken(req.url)
.then(function (authResponse) {
oauth2_token_json = JSON.stringify(authResponse.getJson(), null, 2);
})
.catch(function (e) {
console.error(e);
});
res.send('');
});
9. Once your application has obtained an access token, it can use this token to make Intuit API requests on behalf of the user. This includes making requests for user data, creating transactions, and editing. Include the access token in the Authorization header of your API requests. For example, GET CompanyInfo API:
app.get('/getCompanyInfo', function (req, res) {
const companyID = oauthClient.getToken().realmId;
const url =
oauthClient.environment == 'sandbox'
? OAuthClient.environment.sandbox
: OAuthClient.environment.production;
oauthClient
.makeApiCall({ url: `${url}v3/company/${companyID}/companyinfo/${companyID}` })
.then(function (authResponse) {
console.log(`The response for API call is :${JSON.stringify(authResponse)}`);
res.send(JSON.parse(authResponse.text()));
})
.catch(function (e) {
console.error(e);
});
});
10. Access tokens have a limited lifespan and will eventually expire. Here is how you handle the token expiration and refresh:
app.get('/refreshAccessToken', function (req, res) {
oauthClient
.refresh()
.then(function (authResponse) {
console.log(`The Refresh Token is ${JSON.stringify(authResponse.getJson())}`);
oauth2_token_json = JSON.stringify(authResponse.getJson(), null, 2);
res.send(oauth2_token_json);
})
.catch(function (e) {
console.error(e);
});
});
By following the recommended steps above, you can successfully implement an end-to-end OAuth flow that will provide your customers with a secure method to authorize resource access to your application.
Keep an eye out for the next article in our “Building Smarter with Intuit” series. In the meantime, you might want to read a similar article on change data capture (CDC), which you can find here.