Adding OAuth - Part 1: Setting up an integration

Note: This tutorial uses version 2 of the Zendesk Apps framework (ZAF v2).

If you want to use a third-party service to add functionality to Zendesk Support, you'll probably need to implement OAuth authentication too. Zendesk apps are not authorized to use third-party services on their own. They need permission from a user of the third-party service to access the service on the user's behalf. OAuth is an open standard that allows apps to get that permission from users.

In this three-part series, you'll learn how to add OAuth authentication to a client-side Zendesk app.

  • In Part 1, you'll set up an app that integrates a third-party service in Zendesk Support.
  • In Part 2, you'll modify the app to use OAuth authentication to make requests to the third-party service.
  • In Part 3, you'll build services to manage the OAuth authorization flow. The flow produces an access token that your app uses instead of a password to authenticate requests to the third-party service.

To save time, the tutorial starts with an app built in another tutorial, Sending data to an external application. The app creates tasks in Asana, a popular task management service. The app relies on an Asana personal access token for authentication. The personal access token works only for the developer's own account. You'll change the app to give any agent access to their own Asana account.

Topics covered in Part 1 of the tutorial:

The other tutorials in the series describe how to implement OAuth authentication:

Disclaimer: Zendesk provides this article for instructional purposes only. Zendesk does not support or guarantee the code. Zendesk also can't provide support for third-party technologies such as Asana, Python, and the Bottle web framework. Please post any issue in the comments section or search for a solution online.

OAuth basics

OAuth supports several flows for getting access tokens for API requests. This tutorial describes the most common one, the authorization code grant flow.

The authorization code grant flow has two parts:

  1. In the first part, your app sends the user to the third-party website (Asana in this case) so that the user can instruct the third party to grant your app access to their data on the third-party site. After the user confirms the decision, the third party sends an authorization code to your app notifying it that the user has granted access to your app.
  2. In the second part of the flow, your app exchanges the authorization code for an access token from the third party. The app can then use the access token to authenticate requests to the third-party API.

To learn more, see Using OAuth authentication with your application in the Zendesk Support knowledge base.

Obstacles for client-side Zendesk apps

Implementing OAuth in a client-side Zendesk app (unlike a server-side one) presents the developer with the following challenges:

  • A Zendesk app has no return address
  • Security and cross-domain issues

No return address

As described in OAuth basics above, after the user instructs the third party to grant access to your app, the third party sends the authorization code to a URL that you specify. The authorization code is specified in a query string appended to the URL. Example:

https://{some_domain}/{some_page}?code=7xqwtlf3rrdj8uyeb1yf

The catch is that a Zendesk app doesn't run in a separate browser with its own URL. It runs in the Zendesk Support agent interface. What URL should the third party use to send the authorization code?

One solution is to create a separate, lightweight web app with its own return address. The web app can grab the authorization code from query string and exchange it for an access token.

The server-side application doesn't have to be complicated. Part 3 of this tutorial, Managing the authorization flow, describes how to build one.

Security and cross-domain issues

After the server-side application exchanges an authorization code for a valid access token, the server has to save the token to reuse it.

One possibility is to save the token in a database on the server and then make an AJAX request from the app in Zendesk Support to retrieve the token. Aside from the overhead of managing users and tokens in a database, saving tokens server-side raises security concerns. Access tokens are like passwords. Anybody with access to the database basically has access to the Asana accounts of all your users.

A better solution is for the server to save it in a cookie on the user's computer. It's not completely secure but cookie expiration and server-side encryption can help.

If the server sets a cookie, then your Zendesk app has to retrieve the cookie's value to make authenticated requests.

If your Zendesk app is server-side, then there's no problem. It can get the cookie value from the user's response headers.

If your Zendesk app is client-side as in this tutorial, then the server has to pass the value to the app running in the agent's browser. Simply reading the cookie client-side with some JavaScript won't work. A page in one domain (in this case, the iframe in your Zendesk domain) can't read cookies set in a different domain (by the cookie-setting script in your server domain). It's a browser security feature not specific to Zendesk apps.

The solution is to embed a page from the cookie domain in the Zendesk app using a second iframe, and then use the JavaScript postMessage() method to slip the token to your app page.

The embedded page is never actually displayed in the app. However, because the page is in the same domain as the application that set the cookie, the server can retrieve the cookie's value from the HTTP request for the page and then include it in the page in the HTTP response to the iframe.

Parts 2 and 3 of this tutorial series describe how to embed an iframe in a Zendesk app to communicate with the outside world.

Set up the sample app

To save time, this tutorial provides the files for a client-side sample app developed in another tutorial called Sending data to an external application. The app lets users add tasks in Asana from a ticket in Zendesk Support:

Asana is a popular task management application. If you're not an Asana user, you can sign up for free as described below.

Download the sample app files

  1. If you don't already have one, create a tutorials folder.
  2. Click this article attachment to download the zip file.
  3. Unzip the file and move the add_oauth_v2 folder into your tutorials folder.

Sign up to Asana

If you don't already have an Asana account, you can sign up for free. If you have an account, skip to step 5.

  1. Go to https://asana.com/ and sign up using Google, or enter your email address and click Get Started for Free.
  2. If not using Google, complete your profile by entering your name and a password.
  3. Enter "Support Team" as your team name.

  4. (Optional) If you plan on rolling out the sample app to agents in your Zendesk Support instance, you must invite the agents to join your new team in Asana. Only team members can add tasks in Asana and, by extension, grant an application permission to add tasks on their behalf. To invite agents:

    1. Click your user icon in the upper-right side and select Support Team Settings.
    2. In the Workspace Settings dialog box, click the Members tab.
    3. Enter the email of the agent you want to invite and click Send Invite.

    If the agent isn't already an Asana user, accepting the invitation creates an Asana account for the agent.

  5. Create a project by clicking the Plus (+) icon next to the Projects label on the left side and create a new project named "Tech Notes".
  6. On the Tech Notes project page, click Add Task and enter a sample task to write a tech note on some subject. Example: "Clarify the serial number location".

Specify the Asana project in the sample app

The sample app needs to know the id of your project to add tasks to it. The project id is specified in the app in a hidden form field.

To specify the project

  1. Make sure you're signed into Asana.
  2. In another tab in the same browser, enter the following url in the browser's address bar and press Enter:

    https://app.asana.com/api/1.0/projects

    You should see something like:

    {"data":[{"id":29483377422900,"name":"Learn how to use Asana"},{"id":1555818731072676,"name":"Tech notes"}]}

  3. Copy the "id" value for "Tech notes".
  4. Switch to the tutorial sample files and open the /assets/iframe.html file in a text editor.
  5. In the "project-id" form field, replace the {project_id} placeholder with the id from step 2. Don't keep the curly braces. Example:

    <input type="hidden" name="project-id" id="project-id" value="1555818731072676" />

  6. Save the file.

Click to go to the next tutorial now: Part 2: Changing how requests are authenticated.