Back

How to build a public forms.app integration: Building the Auth Flow

Aug 17, 20247 minute read

Hey there, fellow JavaScript wizards! Ready to dive into the world of forms.app integration? Today, we're focusing on the crucial part of any integration: the auth flow. Let's get your users securely connected and start building something awesome!

Prerequisites

Before we jump in, make sure you've got:

  • Your favorite JavaScript environment set up
  • forms.app API credentials (if you don't have these yet, hop over to their developer portal)
  • A basic understanding of OAuth 2.0 (don't worry, we'll cover the specifics)

Auth Flow Overview

We're implementing the OAuth 2.0 authorization code flow. It sounds fancy, but it's just a secure way to get permission from users to access their forms.app data. Here's the gist:

  1. We send users to forms.app to log in
  2. They approve our app
  3. forms.app sends them back to us with a special code
  4. We exchange that code for access tokens
  5. We use those tokens to make API requests

Simple, right? Let's break it down step-by-step.

Implementing the Auth Flow

Initiating the Auth Request

First, we need to send users to forms.app. Here's how:

const authUrl = `https://forms.app/oauth/authorize?client_id=${YOUR_CLIENT_ID}&redirect_uri=${YOUR_REDIRECT_URI}&response_type=code&scope=forms`; // Redirect the user to authUrl

This URL includes your client ID, where you want users sent back to, and what permissions you're asking for.

Handling the Callback

When users approve your app, forms.app will send them to your redirect URI with a code. Catch it like this:

app.get('/callback', (req, res) => { const code = req.query.code; // Now exchange this code for tokens });

Exchanging the Code for Tokens

Time to trade that code for some sweet, sweet tokens:

const response = await fetch('https://forms.app/oauth/token', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ grant_type: 'authorization_code', code, client_id: YOUR_CLIENT_ID, client_secret: YOUR_CLIENT_SECRET, redirect_uri: YOUR_REDIRECT_URI }) }); const { access_token, refresh_token } = await response.json();

Store these tokens securely - you'll need them to make API requests.

Refreshing Access Tokens

Access tokens don't last forever. When they expire, use the refresh token to get a new one:

const refreshResponse = await fetch('https://forms.app/oauth/token', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ grant_type: 'refresh_token', refresh_token: STORED_REFRESH_TOKEN, client_id: YOUR_CLIENT_ID, client_secret: YOUR_CLIENT_SECRET }) }); const { access_token } = await refreshResponse.json();

Securing the Integration

Security is key! Here are some quick tips:

  • Never store tokens in local storage or cookies on the client-side
  • Use HTTPS everywhere
  • Implement PKCE for added security (especially for mobile or single-page apps)

Making Authenticated Requests

Now for the fun part - using your integration! Here's how to make an API request:

const response = await fetch('https://forms.app/api/v1/forms', { headers: { 'Authorization': `Bearer ${access_token}` } }); const forms = await response.json();

Error Handling and Edge Cases

Things don't always go smoothly. Be prepared to handle:

  • Invalid or expired tokens
  • Network errors
  • API rate limits

Always check the response status and handle errors gracefully.

Testing the Auth Flow

Before you ship, make sure to:

  • Test the full flow manually
  • Write automated tests for token refresh and error scenarios
  • Check how your app behaves when forms.app is down

Conclusion

And there you have it! You've just built a secure auth flow for your forms.app integration. From here, you can start building out the rest of your app's features.

Remember, the auth flow is the foundation of your integration. Get this right, and you're well on your way to creating something amazing. Happy coding, and don't hesitate to dive into the forms.app docs for more details!