One Tap
Sign users in with the Google One Tap widget by verifying its ID token.
The One Tap plugin accepts a Google One Tap ID token, verifies it against Google's JWKS, resolves or creates the matching user, and sets a Kernia session cookie — all from a single tap in the browser.
Installation
Add the plugin to your server
Pass one_tap() with the Google OAuth client id used by the browser widget.
import os
from kernia import KerniaOptions
from kernia.auth import init
from kernia.plugins.one_tap import OneTapOptions, one_tap
from .db import adapter
auth = init(KerniaOptions(
database=adapter,
secret=os.environ["KERNIA_SECRET"],
base_url=os.environ["KERNIA_BASE_URL"],
plugins=[one_tap(OneTapOptions(client_id=os.environ["GOOGLE_CLIENT_ID"]))],
))Add the client plugin
The client plugin renders the One Tap prompt and posts the resulting ID token to Kernia. Pass the same Google client id.
import { createAuthClient } from "better-auth/client";
import { oneTapClient } from "better-auth/client/plugins";
export const authClient = createAuthClient({
baseURL: "/api/auth",
plugins: [
oneTapClient({
clientId: "YOUR_GOOGLE_CLIENT_ID",
}),
],
});Usage
Trigger the prompt
Call authClient.oneTap() (usually on mount of your sign-in page). It shows the
Google prompt, then posts the ID token to /api/auth/one-tap/verify, which
creates the session.
await authClient.oneTap({
fetchOptions: {
onSuccess: () => router.push("/dashboard"),
},
});Render a button instead
To show a styled Google button rather than the auto-prompt:
await authClient.oneTap({
button: {
container: "#signin-button",
config: { theme: "filled_blue", size: "large" },
},
});Options
Server options on OneTapOptions:
| Option | Type | Default | Description |
|---|---|---|---|
client_id | str | None | Google OAuth client id. Falls back to socialProviders.google when omitted. |
provider_id | str | "google" | Provider id linked accounts are stored under. |
disable_sign_up | bool | False | Reject tokens for users with no existing account. |
trusted_provider | bool | True | Trust Google's email_verified claim as authoritative. |
disable_implicit_linking | bool | False | Don't auto-link to an existing user by matching email. |
require_local_email_verified | bool | True | Require the local account email to be verified before linking. |
jwks_url / issuer | str | Google defaults | Override for testing against a non-Google issuer. |
Client options (oneTapClient) include clientId (required), autoSelect,
cancelOnTapOutside, and context ("signin", "signup", or "use").
Schema
No new tables. The user and the linked Google account are written through the
core user and account models.
The client_id on the server must match the one passed to oneTapClient in the
browser, or token verification fails on the audience (aud) check.