π Web Integration Track β
Source:
en/tracks/web.mdΒ· Live: https://docs.1pass.dev/en/tracks/web LLM-sanitized: internal links absolutized, VitePress containers β admonitions, line numbers in the Jump-to Index reference this rendered file (1-indexed).
π Jump-to Index β
- L30-L43: ## The four core promises
- L44-L54: ## Step 1 Β· Register the app
- L55-L91: ## Step 2 Β· Integration patterns
- L57-L81: ### SPA / client-side (recommended)
- L82-L91: ### Server-side (Next.js / Rails / Express)
- L92-L121: ## Step 3 Β· Avoid the web-specific pitfalls
- L122-L131: ## Step 4 Β· Pre-build checks
- L132-L141: ## Common reference (track-agnostic)
- L142-L149: ## Hand the whole thing to an AI
π Web Integration Track β
The fastest path to integrating logi in server-side web apps like Next.js, Rails, and Express.
π‘ Tip: Is this the right track?
- β Yes: a web service that has a backend and that users reach in a browser
- β Mobile app β π± Mobile App Integration Track
- β Pure SPA (no backend) β Public Client + PKCE. See public-clients
- β Desktop SSO (receiving Apple / Google ID tokens directly) β Web SSO (desktop)
The four core promises β
- Confidential client +
client_secretheld server-side. Never expose it in the browser bundle. - redirect_uri is
https://...orhttp://localhostβ the server callback route path. - Verify state + nonce and issue the session with HttpOnly + Secure cookies.
- Keep the app RP and the web RP separate β details: Common / Public Clients Β· One RP per surface
β οΈ Warning: Whether you split or share client_id β the user-identity key is
canonical_subIf you split client_id per surface, the same user receives a different pairwisesubper client; if you share one client_id, you get the samesub. Either way, if the RP keys users bysub, the second-surface login in a split setup can break withAlreadyLinkedError.
β Always identify a person by canonical_sub (always emitted by userinfo), which is identical across all clients. Details: Sub policy
Step 1 Β· Register the app β
β οΈ Warning: Email verification required before registering an app (RP) Before you can register an app (RP) in the developer console, you must verify your email. After signing up, click the link in the verification email, or resend it from the console at
/account. Registration is blocked until you verify. β App registration guide Β· Prerequisite
SPA / client-side β register the RP with
client_type: public(PKCE-only, no secret).Server-side (Next.js / Rails / Express) β register the RP with
client_type: confidentialβ you get aclient_id+client_secret.
Step 2 Β· Integration patterns β
SPA / client-side (recommended) β
For a pure SPA (token exchange directly in the browser, with no backend callback), use the official SDK @logi-auth/browser (v1.0.1 or later):
npm install @logi-auth/browserimport { LogiAuth } from '@logi-auth/browser';
const auth = new LogiAuth({
clientId: 'logi_xxx',
redirectUri: window.location.origin + '/auth/callback',
});
// Page A β start login
await auth.signIn();
// Page B β callback page
const tokens = await auth.handleCallback();For the full API and error classification β SPA Quickstart
Server-side (Next.js / Rails / Express) β
Hold client_secret on the server and handle the callback there. logi provides standard OIDC discovery (https://api.1pass.dev/.well-known/openid-configuration), so general OIDC libraries β oauth4webapi, openid-client, next-auth, auth.js β configure themselves automatically from issuer: 'https://api.1pass.dev' alone.
| Stack | Guide | Core |
|---|---|---|
| Next.js (App Router) | integrations/nextjs | Route Handler + iron-session pattern |
| Rails 8 | integrations/rails | Direct OAuth client (no omniauth). β οΈ With Hotwire/Turbo, data-turbo="false" is required |
| Express.js | integrations/express | cookieParser + crypto PKCE |
Step 3 Β· Avoid the web-specific pitfalls β
β οΈ Warning: β οΈ When adding a web surface to an existing mobile RP, you must update the redirect_uri whitelist When a single
client_idis shared by a mobile app and a web surface (safe for a public + PKCE RP), the web callback URL must also be explicitly registered in the RP'sredirect_uriswhitelist. If it's missing, logi rejects the request immediately:
{ "error": "invalid_request", "error_description": "redirect_uri not registered" }Before you start the web build, always:
# check the currently registered whitelist
logi app show $CLIENT_ID
# if missing, add it (existing URIs are kept; this appends)
logi app update $CLIENT_ID --add-redirect-uri "https://app.example.dev/auth/1pass/callback"
# if you have preview/staging domains, register them too
logi app update $CLIENT_ID --add-redirect-uri "https://preview.example.dev/auth/1pass/callback"
# verify
logi apps verify $CLIENT_ID -r "https://app.example.dev/auth/1pass/callback"This pitfall commonly happens "when bolting a new web flow onto an RP that was already registered for mobile." For a new RP, register the callbacks for every surface up front in the redirect_uris array of the App registration guide.
- Response headers / body signals β
Set-CookieSameSite policy - Web SSO (desktop Apple/Google) β for understanding internals. It is not the starting point for a new RP integration; refer to it only when you want to know how logi handles Apple/Google upstream IdP tokens
- QR login (app push approval) β delegate approval from a desktop web RP to the mobile app
- Widget SDK (iframe embed) β pattern for embedding the login screen in an iframe
- First-login completion form β pattern for your own extra sign-up fields
Step 4 Β· Pre-build checks β
- β
Verify the redirect_uris whitelist β right before build/deploy, run
logi apps verify $CLIENT_ID -r "$WEB_CALLBACK_URL"to check each of your production, staging, and preview domains. Baking it into CI is safest (--json+ exit code). - RP integration testing
- Security best practices (RP side) β state/nonce/CSRF
- Troubleshooting
demo.1pass.dev/qrβ desktop β mobile QR handoff walking sample (scenario deep-links)demo.1pass.dev/oauthβ desktop OAuth (PKCE) walking sample- Demo page walkthrough β per-scenario flow + clean-CSP pattern
Common reference (track-agnostic) β
- Authorization Code Flow Β· PKCE Β· Scope reference
- Error codes Β· Token Introspection & JWKS
- Refresh token policy
- Login button components
- Webhook integration Β· HMAC signature verification
Hand the whole thing to an AI β
Paste @/llms-full.txt into Claude Code, Cursor, or Codex, then say:
"Integrate logi 1pass as an RP into my [Next.js / Rails / Express] web app, using a confidential client + a server-held secret."
β It generates the env, route, controller, callback handler, and login button UI automatically.