OAuth Connection Flow

Application APIs

This guide demonstrates how to handle OAuth connection completion when establishing data connections with third-party healthcare services. After initiating an OAuth connection flow (see Search for & Establish Connections), you need to handle the redirect when users complete authentication. This guide provides two integration options for managing OAuth completion in web and mobile applications.


Prerequisites

Environment URL:

  • Client-Sandbox: https://api.client-sandbox.icanbwell.com/v1/graphql


Authentication Flow

Step 1: Generate OAuth URL

Call the getOauthUrl query with your connectionId to receive a redirectUrl:

GraphQL Query:

query getOauthUrl($connectionId: String!) {
  getOauthUrl(connectionId: $connectionId) {
    redirectUrl
  }
}

Example Variables:

{
  "connectionId": "your-connection-id"
}

Step 2: Open Authentication Window

Open the returned redirectUrl in a new window or webview for the user to complete authentication with the third-party healthcare service.


Step 3: Handle OAuth Completion

Once the user completes (or cancels) the authentication, a redirect will occur. You have two integration options for handling this completion.


Integration Options

Option 1: Default Redirect (Recommended for Web Applications)

With this option, the OAuth flow redirects to a page hosted on b.well infrastructure that provides completion status through multiple mechanisms.

How It Works

  1. After OAuth completion, the user is redirected to a b.well hosted completion page
  2. The page URL is updated with a status_code query parameter
  3. If the authentication window was opened via window.open(), a postMessage is sent to the parent window

Implementation Methods

Method A: PostMessage Listener (Recommended for Web)

Ideal for single-page applications and web contexts.

// Open the OAuth window
const authWindow = window.open(redirectUrl, 'oauth', 'width=500,height=600');

// Listen for completion message
window.addEventListener('message', (event) => {
  // Note: In production, validate event.origin for security
  if (event.data === 'status-success') {
    console.log('OAuth connection successful!');
    authWindow.close();
    // Proceed with your application flow
  } else if (event.data === 'status-failure') {
    console.log('OAuth connection failed');
    authWindow.close();
    // Handle error state
  }
});

Method B: URL Polling (Alternative for Web, Recommended for Mobile)

Suitable for mobile applications or contexts where postMessage isn't available.

// Open the OAuth window
const authWindow = window.open(redirectUrl, 'oauth', 'width=500,height=600');

// Poll for URL changes
const pollInterval = setInterval(() => {
  try {
    const currentUrl = new URL(authWindow.location.href);
    const statusCode = currentUrl.searchParams.get('status_code');
    
    if (statusCode) {
      clearInterval(pollInterval);
      
      if (statusCode === 'success') {
        console.log('OAuth connection successful!');
        authWindow.close();
      } else {
        console.log('OAuth failed with status:', statusCode);
        authWindow.close();
        // Handle specific error cases
      }
    }
  } catch (e) {
    // Cross-origin errors are expected while on third-party domain
  }
}, 500);

Option 2: Custom Redirect URL

With this option, you provide your own redirect URL where users will be sent after OAuth completion. This gives you full control over the completion experience.

How It Works

  1. After OAuth completion, users are redirected directly to your URL
  2. b.well appends the status_code query parameter to your URL

Implementation

Your redirect endpoint will receive requests like:

https://your-domain.com/oauth-callback?status_code=success

Handle the status_code parameter on your server or client application to determine the connection outcome.


Status Codes

Both integration options provide a status_code parameter with one of the following values:

Status CodeDescription
successOAuth flow completed successfully
errorGeneric error occurred during OAuth flow
cancelledUser denied OAuth access
expiredb.well JWT token expired during the flow
unauthorizedCSRF token mismatch (security validation failed)

Best Practices

Security Considerations

Validate Message Origin

When using postMessage, always validate event.origin in production:

window.addEventListener('message', (event) => {
  if (event.origin !== 'https://your-expected-domain.com') {
    return;
  }
  // Process message
});

HTTPS Only

Always use HTTPS for custom redirect URLs in production environments.

Token Handling

Never expose sensitive tokens in client-side code. Handle token exchange and storage on your backend.

User Experience

Window Dimensions

Use appropriate dimensions for the OAuth popup:

window.open(url, 'oauth', 'width=500,height=600,scrollbars=yes');

Timeout Handling

Implement timeout logic for cases where users abandon the flow:

setTimeout(() => {
  if (authWindow && !authWindow.closed) {
    authWindow.close();
    // Handle timeout
  }
}, 300000); // 5 minutes

Loading States

Show appropriate loading indicators while waiting for OAuth completion.

Mobile Considerations

In-App Browsers

Use in-app browser components (WKWebView, Chrome Custom Tabs) for better user experience.

Deep Links

When using custom redirect URLs, configure deep links to return users to your app.

URL Polling

Prefer URL polling over postMessage in mobile webviews for more reliable completion detection.