OAuth

Configure OAuth providers and complete the login flow.

Overview

The Auth fragment supports OAuth providers like GitHub. When enabled, it exposes two routes:

  • GET /oauth/:provider/authorize to generate the provider authorization URL
  • GET /oauth/:provider/callback to exchange the code, issue a credential, and set the fragno_auth cookie

OAuth is disabled unless you configure providers in the fragment config.

Configure providers

import { createAuthFragment, github } from "@fragno-dev/auth";

export const authFragment = createAuthFragment(
  {
    oauth: {
      defaultRedirectUri: "https://your-app.com/api/auth/oauth/github/callback",
      providers: {
        github: github({
          clientId: process.env.GITHUB_CLIENT_ID!,
          clientSecret: process.env.GITHUB_CLIENT_SECRET!,
        }),
      },
    },
  },
  fragnoConfig,
);

Notes:

  • defaultRedirectUri is used when the provider does not specify redirectURI.
  • You can override per provider with redirectURI.
  • linkByEmail defaults to true and links OAuth accounts to existing users by email.
  • tokenStorage controls what gets stored on the OAuth account: "none", "refresh", or "all".
  • Set emailAndPassword.enabled to false to disable email/password sign-up and sign-in.

Client flow

const { oauth } = createAuthFragmentClients();
const { url } = await oauth.getAuthorizationUrl({
  provider: "github",
  returnTo: "/app",
});

window.location.assign(url);

When the user finishes the provider flow, the callback route:

  • validates the code
  • creates or links a user
  • sets the fragno_auth cookie
  • returns an auth envelope when it responds with JSON
  • redirects to returnTo if provided

returnTo must be a relative path starting with / and is sanitized server-side.

Proxying auth routes

If you forward /api/auth/* to another worker or Durable Object with fetch, make sure redirects are not auto-followed. The callback returns a 302 with Set-Cookie and Location headers, and the browser needs to receive that redirect directly.

const proxyRequest = new Request(request, { redirect: "manual" });
const response = await authDo.fetch(proxyRequest);
return new Response(response.body, response);

GitHub OAuth

  1. Create a GitHub OAuth App.
  2. Set the callback URL to your fragment callback route.
  3. Start the flow from your UI and let the server callback set the fragno_auth cookie.

Example button:

const handleGithubLogin = async () => {
  const { url } = await authClient.oauth.getAuthorizationUrl({
    provider: "github",
    returnTo: "/app",
  });
  window.location.assign(url);
};

Linking a provider to an existing user

If a user is already signed in, you can link an OAuth provider to their account:

const { url } = await authClient.oauth.getAuthorizationUrl({
  provider: "github",
  link: true,
});
window.location.assign(url);

This requires a valid fragno_auth cookie or Authorization: Bearer <token> on the authorize request.