[New post] Zapier: Authentication Using Session Auth
vishalicious posted: " Building an integration with Zapier starts with authentication. This gives Zapier the ability to use the given user's credentials to log into an application and access the parts of its API that have been connected to Zapier. For me, this was the hardest "
Building an integration with Zapier starts with authentication. This gives Zapier the ability to use the given user's credentials to log into an application and access the parts of its API that have been connected to Zapier. For me, this was the hardest part of building an integration between Zapier and our company's application, AIMM.
Initially, I was only able to get authentication working with a single, hard-coded user. This worked for testing purposes and to let me create Zaps between AIMM and other programs, but it wouldn't suffice for a production environment in which multiple users from different companies had to log in.
Zapier supports 5 types of authentication: basic auth, session auth, API key auth, OAuth v2 and digest auth. AIMM's backend already worked using session auth and JavaScript Web Tokens (JWTs) so when I initially met with the more seasoned developers who are building the application, we decided to make use of that with Zapier as well. This guide will walk through how I set up session auth.
Prerequisites
Before you begin configuring Zapier to authenticate to your backend, you need to have some pieces of data:
You need to have the URL to the endpoint that's used by your application's backend for authentication and JWT issuance
You need to know how to make a web request for that token (ideally, test this using Postman or Insomnia)
You need to have login credentials to use for authentication
In my case, AIMM's backend was documented using a tool that was new to me called Swagger. Swagger essentially uses JavaScript on the backend to describe an API's endpoints which allows it to render a page that displays those endpoints and make test requests to it. Our TL gave me the URL for the endpoint that's used for authentication and token issuance and told me how to structure the request. I tested it both in Swagger and with Insomnia, to make sure that I could get it to work, because I had to duplicate that process in Zapier.
Below is what it looked like in Insomnia. I've removed the endpoint address from the POST request and the credentials from the header. The token itself (access_token) is expired, so that piece of data hasn't been obscured.
Once you know how to get a token from your application's backend, you also need to know how to include it in any needed requests to the backend. For example, one of the endpoints in our backend returns an array of all customers. This is used to display a customer list for a given company in our application. Different endpoints might have additional requirements when making a request. Some might need additional information in the request header, or might need a JSON object in the request body, so make sure you know how to properly structure a request to any endpoints you need to connect Zapier with. Test these requests using Postman or Insomnia.
Below is an example of a request in Insomnia to retrieve all customers' data from AIMM's API (yes, its a POST request, not a GET request). Note that the request sends JSON in the request body as well as the token in the header.
Armed with this information (the data needed to get a JWT and the data needed to test that token with an API call) we can begin configuring Zapier.
Authentication
A working authentication is the first step in setting up a Zapier integration. The token that's returned by the API will be used to authorize any API calls made by Zaps once the integration is built. So, what we're doing here is telling Zapier how to talk to our backend for all future transactions.
The process for setting up authentication is as follows:
Configure authentication fields (essentially, create a form that collects the user's login information so that Zapier can use it)
Configure a token exchange request (use data from the authentication fields to connect to an endpoint and retrieve a JWT)
Configure a test request (use the token and call an endpoint to verify that API calls work)
(optional) Set up a connection label (each connection authenticates to the API to get a token; this represents different users - I labeled each connection with the name of the company followed by the username)
Test the authentication
Let's walk through it.
Create a new integration
First, if you don't have a Zapier account, create one. Once you do have one, log in. Next, scroll to the bottom of the website and click on "Developer Platform". Once that page loads, click on "My Integrations" at the top of the screen.
From here, click on the blue "Start a Zapier Integration" button at the top of the screen and complete the form to set up your integration. All of the fields should be relatively easy to fill out. Their names and purposes are self-explanatory (Name, Description, Homepage URL, Logo, Intended Audience, Role, Category) and have brief descriptions under their labels. The last 3 use drop-downs from which answers can be selected.
Click "Create" when you're done and you move on to the integration's configuration section. On the left is a sidebar which displays the selected menu item in the right pane. We want to focus on the "Build" section. We'll start with "Authentication" and in later posts, we'll examine "Triggers" and "Actions".
Configure authentication fields
Click on the blue "Set Up Authentication" button in the right pane. We're given a list of authentication options that Zapier supports. For our purposes, we're going to go with Session Auth. Click the blue "Save" button at the bottom of the screen.
We're now take to the Session Auth configuration screen. Lets walk through how I set up session authentication for AIMM:
Configure your fields
In the "Step 1" section, we add fields that will be used to create a form which users will fill out with their login information for the application being integrated with Zapier. For AIMM, this required three fields: company name, username and password. There is a 4th field with a value that never changes that we'll look at in the next step.
Click on "Add Fields" and complete the form to add a new field. There are two field types: field and computed field. We want to use the first one: field. This created user-fillable fields. The second one uses data that we pass in, programmatically.
Label is what the user will see in the form.
Key is what we'll see when we manipulate the field using JavaScript.
Check the box to mark each field as "required" if it is (all of the ones I used are).
Type is generally going to be string, for which you can just leave the field blank.
Change Type to "Password" if you want typed characters to appear as asterisks onscreen.
For testing purposes, you can give each field a default value. This will appear in the field's input box when the login screen is shown to the user, but can be overwritten by typing over it. Click the "Add" button at the bottom of the screen when you're finished completing the form for the current field and then repeat the process for any others that are needed. Once all of the fields that the user needs to fill out are defined, click the blue "Continue" button.
When I was done, my authentication fields looked like this:
Configure a token exchange request
With the login fields defined, we move onto the token exchange request, or Step 2. This is the step for which we gathered information in the prerequisites step, above. For this step, switch to code mode. Refer to the testing that you completed with Postman or Insomnia and modify the provided code in the editor with the settings and parameters that your API needs to get a JWT. You'll need your token exchange endpoint, any necessary headers, params and/or JSON for the body. You'll also need to know what your API calls the token that it produces. Find this in the response body from Insomnia or Postman.
This is what the token exchange code to connect to AIMM looks like:
Note that the AIMM request has no params, but does have headers and a request body. To get the values that the user types into the form we configured in Step 1, we preface each field name with "bundle.authData." As mentioned in Step 1, a 4th field is added to the request body here: grant_type. The value of this field is always "password" so we supply it here and the user doesn't need to know about it.
"access_token" is the name of the JWT returned from AIMM's API. Your application probably uses a different name, which can be found by examining the response body for your token request in Postman or Insomnia. Return that value, so that Zapier holds onto it for the next step.
As an aside, Zapier has its own global object, much like "window" or "console" in JavaScript. Its simply called "z". If you need to run any tests, like console.log, use "z.console.log" to make them work.
Click "Save & Continue".
Configure a test request & connection label
Now we come to Step 3, in which Zapier will use data from the user-inputted fields and the token from the previous two steps to call an API endpoint and perform an action. For my test, I called an endpoint in AIMM that returns all of the customers for a given company (the company that the user specified during login). You can call any endpoint that you'd like from your application's API as long as you know all of the parameters that it needs to make the call. In my case, no special parameters were needed; no params and no request body. All I needed were the endpoint's URL and the right headers, which included the JWT gotten from Step 2.
Like before, switch to code mode and modify the pregenerated code to connect to your chosen endpoint. The test endpoint connection used to test AIMM looked like this:
const options = { url: '[removed for privacy, use the URL from Postman/Insomnia]', method: 'POST', headers: { 'content-type': 'application/json', 'Authorization': 'Bearer ' + bundle.authData.accessToken, }, params: { }, body: { } } return z.request(options) .then((response) => { response.throwForStatus(); const results = response.json; // You can do any parsing you need for results here before returning them return results; });
Note that the Authorization key in the headers object includes a value which passes in the JWT obtained in Step 2. The format that your application's API uses to pass in the token might differ from what AIMM's API uses, so consult the test from Postman or Insomnia to make sure that its correct.
There's an optional step in which the connection label can be named. I switched to code mode here as well and configured the label to include the company name followed by the username of the person whose credentials were being used to make the connection to AIMM. It looks like this:
The field names used by your application will differ, of course, but its probably not a bad idea to at least configure the label to at least use the username of the person who is authenticating. This is especially useful if several people share the same computer and use it to access the integrated application.
Click "Save & Continue".
Test your authentication
Finally, we come to the last step: testing the authentication. Here, we'll use the information that the user provides in the form we created to authenticate to the server and get a JavaScript web token, and then we'll send that token along in an HTTP request to an endpoint at the API.
If everything works, we'll get a successful response and avoid the weeks of self-doubt and dismay that I experienced the first time I tried to make this work. If it doesn't work, fall back on your troubleshooting skills and examine the error message for clues as to why the world is spinning so uncontrollably off-course.
First, click the blue "Sign in" button in the middle of the section. If you're re-testing, you can click the drop-down here to add a new account or choose from an existing one. A sign-in modal will appear containing the fields that were defined in Step 1. Fill out the form and submit it. Zapier will take that information and use it to try and get a token from the application's API.
If it succeeds, click on "Test Authentication" to use that token to make an API call to the endpoint specified in Step 3. The results, for good or for ill, will be displayed in the Step 4 section.
You should be able to click on the Response, Bundle, HTTP and, in some cases, Console tabs in Step 4 to view their contents. Response will have the server response from the application's API - or an error.
If things went well, click "Save & Finish". You've done it. You've caused Zapier to authenticate to your application's API and make an HTTP request. Congratulations!
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.