Hey there, fellow JavaScript enthusiasts! Ready to dive into the world of UKG Pro integrations? Today, we're going to tackle one of the most crucial aspects of building a public integration: the authorization flow. Buckle up, because we're about to make your integration secure and user-friendly in no time!
Before we jump in, make sure you've got:
Let's kick things off by getting our project ready:
mkdir ukg-pro-integration cd ukg-pro-integration npm init -y npm install express axios dotenv
Head over to your UKG Pro developer portal and snag your client ID and client secret. While you're there, set up your redirect URI. We'll use http://localhost:3000/callback
for this example.
Create a .env
file in your project root and add these:
UKG_CLIENT_ID=your_client_id
UKG_CLIENT_SECRET=your_client_secret
UKG_REDIRECT_URI=http://localhost:3000/callback
Now for the fun part! Let's build out our auth flow:
require('dotenv').config(); const express = require('express'); const axios = require('axios'); const app = express(); const authorizationUrl = `https://ukg.com/oauth/authorize?client_id=${process.env.UKG_CLIENT_ID}&redirect_uri=${encodeURIComponent(process.env.UKG_REDIRECT_URI)}&response_type=code`; app.get('/login', (req, res) => { res.redirect(authorizationUrl); }); app.get('/callback', async (req, res) => { const { code } = req.query; try { const response = await axios.post('https://ukg.com/oauth/token', { grant_type: 'authorization_code', client_id: process.env.UKG_CLIENT_ID, client_secret: process.env.UKG_CLIENT_SECRET, code, redirect_uri: process.env.UKG_REDIRECT_URI }); const { access_token, refresh_token } = response.data; // Store these tokens securely (more on this later) res.send('Authorization successful!'); } catch (error) { console.error('Error during token exchange:', error); res.status(500).send('Authorization failed'); } }); app.listen(3000, () => console.log('Server running on http://localhost:3000'));
Storing tokens securely is crucial. In a production environment, you'd want to use a secure database or key management service. For now, let's keep it simple:
let tokens = { access_token: null, refresh_token: null }; // In your callback route: tokens.access_token = response.data.access_token; tokens.refresh_token = response.data.refresh_token;
To refresh the token:
async function refreshToken() { try { const response = await axios.post('https://ukg.com/oauth/token', { grant_type: 'refresh_token', client_id: process.env.UKG_CLIENT_ID, client_secret: process.env.UKG_CLIENT_SECRET, refresh_token: tokens.refresh_token }); tokens.access_token = response.data.access_token; // The refresh token might also be updated if (response.data.refresh_token) { tokens.refresh_token = response.data.refresh_token; } } catch (error) { console.error('Error refreshing token:', error); } }
Now that we've got our tokens, let's use them:
async function makeUKGRequest(endpoint) { try { const response = await axios.get(`https://ukg.com/api/${endpoint}`, { headers: { Authorization: `Bearer ${tokens.access_token}` } }); return response.data; } catch (error) { if (error.response && error.response.status === 401) { await refreshToken(); // Retry the request return makeUKGRequest(endpoint); } throw error; } }
We've already handled token expiration in our makeUKGRequest
function. For other errors, make sure to implement proper error handling and logging.
Remember to:
Set up a test environment and write some unit tests. Here's a quick example using Jest:
const axios = require('axios'); jest.mock('axios'); test('makeUKGRequest refreshes token on 401', async () => { axios.get.mockRejectedValueOnce({ response: { status: 401 } }); axios.get.mockResolvedValueOnce({ data: 'success' }); axios.post.mockResolvedValueOnce({ data: { access_token: 'new_token' } }); const result = await makeUKGRequest('some-endpoint'); expect(result).toBe('success'); expect(axios.post).toHaveBeenCalledWith('https://ukg.com/oauth/token', expect.any(Object)); });
And there you have it! You've just built a solid foundation for your UKG Pro integration. Remember, this is just the beginning. As you expand your integration, keep security at the forefront, and don't hesitate to dive into UKG's documentation for more advanced features.
Happy coding, and may your integrations be ever secure and efficient!