I’m working on implementing HubSpot’s OAuth authentication in my web app. Everything works great when users are already signed into their HubSpot accounts, but I run into problems when they need to log in first.
When a user who isn’t logged in tries to connect, they get redirected to HubSpot’s login page in a popup window. After they enter their credentials and complete the login, the token exchange doesn’t work properly. The weird thing is that the exact same process works perfectly for users who are already authenticated.
Here’s my implementation:
const authResponse = await fetch('https://api.hubapi.com/oauth/v1/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: requestData.toString()
});
const authData = { ...authResponse.data, authCode };
console.log('Auth data received:', authData);
return res.status(200).send(
`<html>
<head><title>HubSpot Connection</title></head>
<body>
<h1>Successfully Connected to HubSpot!</h1>
<p>This window will close automatically.</p>
<button onclick="window.close()">Close Window</button>
<script>
console.log(window.opener);
if (window.opener) {
window.opener.postMessage(${JSON.stringify(authData)}, "http://localhost:3000/settings");
}
console.log(window.location);
</script>
</body>
</html>`
);
I’ve tried several things to debug this:
- Verified that the token exchange request is actually being sent
- Confirmed that identical requests work for pre-authenticated users
- Reviewed HubSpot’s OAuth docs and verified my redirect URLs and permissions
- Found that tokens are generated but the popup-to-parent communication breaks
Any ideas what might be causing this difference in behavior?