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/authorizeto generate the provider authorization URLGET /oauth/:provider/callbackto exchange the code, create a session, and set the 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:
defaultRedirectUriis used when the provider does not specifyredirectURI.- You can override per provider with
redirectURI. linkByEmaildefaults totrueand links OAuth accounts to existing users by email.tokenStoragecontrols what gets stored on the OAuth account:"none","refresh", or"all".- Set
emailAndPassword.enabledtofalseto 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 session cookie
- redirects to
returnToif 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
- Create a GitHub OAuth App.
- Set the callback URL to your fragment callback route.
- Start the flow from your UI and let the server callback set the session 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 session cookie on the authorize request.