Hey there, fellow JavaScript enthusiasts! Ready to dive into the world of SignRequest integrations? Today, we're going to tackle one of the most crucial aspects of building a public integration: the authorization flow. Trust me, getting this right is key to creating a secure and user-friendly experience. So, let's roll up our sleeves and get to work!
Before we jump in, make sure you've got:
Let's kick things off by setting up our project:
mkdir signrequest-integration cd signrequest-integration npm init -y npm install express axios dotenv
Create a basic server.js
file:
require('dotenv').config(); const express = require('express'); const app = express(); const PORT = process.env.PORT || 3000; app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
SignRequest uses OAuth 2.0 with the authorization code grant type. In a nutshell, it goes like this:
Simple, right? Let's implement it!
First, let's create a route to start the auth process:
const SIGNREQUEST_AUTH_URL = 'https://signrequest.com/api/v1/oauth2/authorize/'; app.get('/auth', (req, res) => { const authUrl = new URL(SIGNREQUEST_AUTH_URL); authUrl.searchParams.append('client_id', process.env.SIGNREQUEST_CLIENT_ID); authUrl.searchParams.append('redirect_uri', process.env.REDIRECT_URI); authUrl.searchParams.append('response_type', 'code'); res.redirect(authUrl.toString()); });
Now, let's set up our redirect URI to handle the callback:
app.get('/callback', async (req, res) => { const { code } = req.query; if (!code) { return res.status(400).send('Authorization code missing'); } // We'll exchange the code for a token in the next step });
Let's add the token exchange logic to our callback route:
const axios = require('axios'); app.get('/callback', async (req, res) => { const { code } = req.query; if (!code) { return res.status(400).send('Authorization code missing'); } try { const response = await axios.post('https://signrequest.com/api/v1/oauth2/token/', { grant_type: 'authorization_code', code, redirect_uri: process.env.REDIRECT_URI, client_id: process.env.SIGNREQUEST_CLIENT_ID, client_secret: process.env.SIGNREQUEST_CLIENT_SECRET, }); const { access_token, refresh_token } = response.data; // Store these tokens securely (e.g., in a database) // For this example, we'll just send them in the response res.json({ access_token, refresh_token }); } catch (error) { console.error('Error exchanging code for token:', error.response?.data || error.message); res.status(500).send('Error obtaining access token'); } });
To keep your integration running smoothly, you'll need to refresh the access token when it expires. Here's a simple function to do that:
async function refreshAccessToken(refresh_token) { try { const response = await axios.post('https://signrequest.com/api/v1/oauth2/token/', { grant_type: 'refresh_token', refresh_token, client_id: process.env.SIGNREQUEST_CLIENT_ID, client_secret: process.env.SIGNREQUEST_CLIENT_SECRET, }); return response.data.access_token; } catch (error) { console.error('Error refreshing token:', error.response?.data || error.message); throw error; } }
Now that we have our access token, we can make authenticated requests to the SignRequest API. Here's an example of how to use it:
async function createSignRequest(access_token, documentData) { try { const response = await axios.post('https://signrequest.com/api/v1/signrequests/', documentData, { headers: { 'Authorization': `Bearer ${access_token}`, 'Content-Type': 'application/json', }, }); return response.data; } catch (error) { console.error('Error creating sign request:', error.response?.data || error.message); throw error; } }
Always be prepared for things to go wrong. Here are some tips:
Before you ship it, make sure to thoroughly test your integration:
And there you have it! You've just built a robust authorization flow for your SignRequest integration. Remember, this is just the beginning. From here, you can expand your integration to leverage all the awesome features SignRequest has to offer.
Keep coding, keep learning, and most importantly, keep having fun with it!
Happy integrating!