OpenTrip Docs
BackendHTTP API

Authentication and session

Authentication and session

Auth is Better Auth mounted at /api/auth/*. See auth.md for server config, captcha, Google/WeChat OAuth, and defaultCurrency.

Session model for non-browser clients

  1. Session middleware runs on every request: auth.api.getSession({ headers }).
  2. Business routes under /api (except health, invite preview, uploads) require a session; otherwise 401.
  3. The web app sends cookies with credentials: "include" (apps/web/src/shared/api/client.ts).
  4. Mobile / native apps should:
    • Point the Better Auth client (or equivalent HTTP) at the same API origin and base path /api/auth.
    • Persist and re-send the session cookie (cookie jar / Cookie header) on every API call after sign-in. CORS credentials: true and TRUSTED_ORIGINS apply to browser clients; native apps talking to the API origin directly rely on cookie storage, not browser CORS.
    • Prefer the official Better Auth client for the platform when available so sign-in, sign-up, session refresh, and sign-out stay compatible.

The native WeChat Mini Program client is bearer end-to-end. It exchanges wx.login() for a session token, stores it in Mini Program storage, and sends Authorization: Bearer … on every business request. There is no cookie handoff and no WebView bridge. See ../../frontend/miniapp.md.

Client-relevant Better Auth surfaces

Not every Better Auth plugin path is listed here. Clients need at least:

ActionTypical path (under /api/auth)Notes
Email sign-upPOST …/sign-up/emailCreates unverified user; OTP emailed. Captcha when enabled
Verify email OTPPOST …/email-otp/verify-emailMarks verified + auto sign-in
Resend email OTPPOST …/email-otp/send-verification-otpCaptcha when enabled
Email sign-inPOST …/sign-in/emailUnverified → EMAIL_NOT_VERIFIED + OTP resent
Social sign-inPOST …/sign-in/socialGoogle or WeChat web QR when configured
Mini Program WeChat sign-inPOST …/wechat-mini-program/sign-inBody { code } from wx.login(); returns the normal Better Auth session token
SessionGET …/get-sessionCurrent user + session
Sign-outPOST …/sign-outClears session
Update userBetter Auth updateUsere.g. name, defaultCurrency

Native OAuth bridge

MethodPathPurpose
GET/api/mobile-auth/oauth/start?provider=google302 to Google with Better Auth OAuth state cookies (open inside ASWebAuth)
GET/api/mobile-auth/oauth/completeConvert the browser cookie session to a one-time app callback code
POST/api/mobile-auth/oauth/exchangeConsume { code } and return { token, session }

The callback code is hashed at rest, valid for three minutes, and consumed on first use. Native business requests send the returned session token as a Bearer credential.

The former mobile-auth/webview/mint and mobile-auth/webview/exchange bridge endpoints were removed with the WebView shell (0011).

Cloudflare Turnstile (when CAPTCHA_PROVIDER=cloudflare-turnstile) intercepts protected auth POSTs via header x-captcha-response. Other CAPTCHA providers are not supported. See auth.md.

Avatar image for the signed-in user is not only Better Auth: use POST/DELETE /api/users/avatar so storage and profile stay consistent.


← API index · Auth deep-dive

On this page