Skip to main content

Local Development Quickstart

Doc type: Tutorial

Goal and expected outcome

Your local app signs users in via https://auth-int.yoyogroup.com, receives an OAuth authorization code, exchanges it for tokens, and bootstraps a local session.

Prerequisites and setup

  • You have a registered OAuth2 client ID (client_id) with localhost redirect URIs configured.
  • Your local app can handle the OAuth callback route.
  • You can reach the integration hosted auth portal at https://auth-int.yoyogroup.com.
  • Optional starter: use examples/yoyo-auth-spa-example as a working boilerplate.

Note: OAuth2 clients are configured in code in lib/app-config.ts. For localhost development, you can use the built-in local-dev client ID, or configure your own client with exact redirect URIs (no wildcards allowed).

Step 1: Create a local callback route

Create a route like /auth/callback that can read code and state query parameters.

Step 2: Build the authorize URL

Use the OAuth authorization endpoint on the hosted portal. This will redirect the user to the hosted login page where they can enter their credentials.

https://auth-int.yoyogroup.com/api/oauth/authorize?response_type=code&client_id=local-dev&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Fcallback&code_challenge=<code_challenge>&code_challenge_method=S256&state=<state>

Optional email parameter: You can include an email query parameter to prefill the email address on the login page. If the email domain is yoyogroup.com, the OKTA SSO flow will be automatically initiated:

https://auth-int.yoyogroup.com/api/oauth/authorize?response_type=code&client_id=local-dev&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Fcallback&code_challenge=<code_challenge>&code_challenge_method=S256&state=<state>&email=user%40yoyogroup.com

Important: The redirect_uri must exactly match one of the configured redirect URIs for your client ID. Wildcards are not allowed in redirect URIs.

Note: When initiated from an SPA, the OAuth flow redirects to the hosted login page instead of an external identity provider. After the user successfully logs in with their credentials, they will be redirected back to your app with the authorization code.

Step 3: Exchange the code for tokens

From your local callback route, post the code and PKCE verifier to the token endpoint.

const response = await fetch('https://auth-int.yoyogroup.com/api/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'authorization_code',
client_id: 'local-dev', // Use your registered client_id
redirect_uri: 'http://localhost:3000/auth/callback', // Must exactly match authorize request
code,
code_verifier
})
});

const tokens = await response.json();

Response format:

{
"access_token": "...",
"id_token": "...",
"refresh_token": "...",
"expires_in": 3600,
"token_type": "Bearer"
}

Step 4: Bootstrap your local session

Store the tokens in memory or your preferred local storage, then use the access token to call your APIs.

Step 5: Use the reference boilerplate app

For complete working examples, see:

  • examples/yoyo-auth-spa-example - React + Vite SPA example demonstrating OAuth2 PKCE flow
  • examples/yoyo-auth-nextjs-example - Next.js integration example with OAuth flow

For a complete single-page example, run:

pnpm --filter yoyo-auth-spa-example dev

The project lives in apps/yoyo-auth-spa-example and implements:

  • State + PKCE generation.
  • Redirect to /api/oauth/authorize.
  • Token exchange at /api/oauth/token.
  • In-browser session display after successful exchange.

Verify the result

  • The hosted portal redirects back to http://localhost:3000/auth/callback.
  • The token exchange returns access_token.

If you need to test shared cookies, run your app on a subdomain of *.yoyogroup.com (for example dev-app.int.yoyogroup.com) so the cookies scoped to .yoyogroup.com are sent to your app.

Client configuration

OAuth2 clients are configured in code in lib/app-config.ts via the getCodeBasedOAuth2Clients() function. The built-in local-dev client supports:

  • http://localhost:3001/auth/callback
  • http://127.0.0.1:3001/auth/callback
  • http://localhost:5173/auth/callback

To add your own client, edit lib/app-config.ts and add a client configuration with exact redirect URIs (no wildcards allowed).