OAuth (Browser, Native & ID Token)
Browser redirect OAuth, native app custom URL schemes, and native Apple/Google sign-in without a browser.
OAuth (browser redirect)
await postbase.auth.signInWithOAuth({
provider: 'google', // or 'github', 'discord', 'apple', etc.
options: { redirectTo: 'https://yourapp.com/callback' },
})OAuth (native apps — custom URL scheme)
For iOS, macOS, or Android apps using an in-app browser (ASWebAuthenticationSession / Chrome Custom Tab), pass your app’s custom URL scheme as redirectTo. The server callback redirects to it instead of an https:// URL, and your app receives the session tokens in the URL.
// Opens the authorize URL — in native environments, open it in an
// ASWebAuthenticationSession or Chrome Custom Tab instead of a browser tab.
const authorizeUrl = await postbase.auth.signInWithOAuth({
provider: 'github',
options: { redirectTo: 'com.myapp://auth/callback' },
})
// After the in-app browser calls back to your app URL, parse the session:
const { data, error } = await postbase.auth.handleOAuthCallback({
url: 'com.myapp://auth/callback?access_token=...&refresh_token=...',
})Sign in with Apple / Google (native SDK — no browser)
For iOS/macOS apps using ASAuthorizationController (Apple) or GIDSignIn (Google), skip the browser entirely and pass the token straight to Postbase:
// iOS — Apple Sign In (Swift → pass identityToken to your JS layer)
const { data, error } = await postbase.auth.signInWithIdToken({
provider: 'apple',
idToken: appleCredential.identityToken, // string JWT from ASAuthorizationAppleIDCredential
nonce: nonce, // optional — include if you passed a nonce to ASAuthorizationAppleIDRequest
rememberMe: true, // optional — 30-day refresh token instead of the default 7-day
})
// Android / Web — Google Sign-In
const { data, error } = await postbase.auth.signInWithIdToken({
provider: 'google',
idToken: googleCredential.idToken, // string JWT from GIDSignIn / Google Identity Services
rememberMe: true, // optional
})
// data.session.accessToken, data.session.refreshToken, data.userNote: For Apple, the provider must be enabled in your Postbase dashboard. The
clientIdfield should contain your Apple Service ID (for web) or comma-separated list of Bundle IDs (for native), matching theaudclaim in Apple’sid_token.
Handle OAuth Callback
In browser apps, call this on the page your redirectTo URL points to — it reads window.location.search automatically:
// pages/callback.tsx (or equivalent)
const { data, error } = await postbase.auth.handleOAuthCallback()
// data.session, data.userFor native apps, pass the URL your app scheme received:
const { data, error } = await postbase.auth.handleOAuthCallback({
url: incomingUrl, // e.g. 'com.myapp://auth/callback?access_token=...'
})Set Session (SSR — persist OAuth session as a cookie)
After handleOAuthCallback() resolves on the client, forward the session to your API route and call setSession on a server client so the session is stored as an httpOnly postbase-session cookie. Subsequent SSR requests are authenticated automatically.
// app/auth/callback/page.tsx (Client Component)
'use client'
import { createBrowserClient } from 'postbasejs/ssr'
const postbase = createBrowserClient(
process.env.NEXT_PUBLIC_POSTBASE_URL!,
process.env.NEXT_PUBLIC_POSTBASE_ANON_KEY!,
{ projectId: process.env.NEXT_PUBLIC_POSTBASE_PROJECT_ID! }
)
const { data, error } = await postbase.auth.handleOAuthCallback()
if (data.session) {
await fetch('/api/auth/callback', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ session: data.session }),
credentials: 'include',
})
}
router.push('/dashboard')// app/api/auth/callback/route.ts (API Route)
import { cookies } from 'next/headers'
import { createServerClient } from 'postbasejs/ssr'
export async function POST(req: Request) {
const { session } = await req.json()
const cookieStore = await cookies()
const postbase = createServerClient(
process.env.NEXT_PUBLIC_POSTBASE_URL!,
process.env.NEXT_PUBLIC_POSTBASE_ANON_KEY!,
{
projectId: process.env.NEXT_PUBLIC_POSTBASE_PROJECT_ID!,
cookies: {
getAll: () => cookieStore.getAll(),
setAll: (cs) => cs.forEach(c => cookieStore.set(c.name, c.value, c.options as any)),
},
}
)
const { error } = await postbase.auth.setSession(session)
if (error) return Response.json({ error }, { status: 400 })
return Response.json({ ok: true })
}The server client writes a postbase-session httpOnly cookie that createServerClient reads on every subsequent request — no manual cookie parsing needed.