A small Express app that logs you in via Splitwise's Authorization Code + PKCE OAuth flow and shows your account on a dashboard. Use this as a template for any web app that needs to access another user's Splitwise data (not just the app owner's).
-
Register an app at https://secure.splitwise.com/apps. Set the Callback URL to:
http://localhost:3000/auth/callback -
Copy the Consumer Key and Consumer Secret from the app page.
-
Install dependencies and run:
cd examples/web-auth-code npm install SPLITWISE_CONSUMER_KEY=... \ SPLITWISE_CONSUMER_SECRET=... \ SESSION_SECRET=any-random-string \ npm start -
Open http://localhost:3000 in your browser. Click "Log in with Splitwise"; you'll bounce out, approve, and bounce back to the dashboard.
- Authorization Code + PKCE — the SDK generates the redirect URL,
state(CSRF token), andcodeVerifierfor you. The app's only job is to persiststateandcodeVerifiersomewhere durable until the callback fires (this demo uses an express-session cookie). Splitwise.fromAuthorizationCode()— the SDK exchanges the callbackcode(plus yourcodeVerifier) for an access token in one call. Returns a fully-configuredSplitwiseclient.sw.getOAuthToken()— pulls the fullOAuthToken(withexpiresAtandrefreshTokenif Splitwise provided them). Persist this on the session and rebuild the client fromaccessTokenon subsequent requests.- State validation — the demo checks
statematches before exchanging the code (CSRF protection). - Typed error handling —
SplitwiseAuthenticationErrortriggers a graceful redirect to the login page; everything else falls through to the generic 500 handler.
Splitwise's OAuth issuer requires client_secret on the token exchange,
even with PKCE. That means the secret can't live in browser-deliverable JS
— you need a server to do the exchange and hold the resulting token. This
demo's backend is intentionally tiny (one file, ~300 lines including
inline HTML) so you can copy the relevant bits into your own server-side
framework of choice.
This is a demo; do not ship it as-is. For production you'll want:
- HTTPS (set
cookie.secure: trueon the session middleware once you have it). - A real session store (the default in-memory store loses sessions on restart and leaks RAM).
- CSRF protection on the
POST /logoutroute (and any other state-changing routes you add). - A cookie-signing secret loaded from a secret manager, not an env var.
- Rate limiting on
/loginand/auth/callback. - Proper logging / observability — use the SDK's
hooksconstructor option to feed your APM tool.