Files
happy-life-star/docs/superpowers/specs/2026-05-08-mini-program-auth-restore-design.md
T

6.1 KiB

Mini Program Auth Restore And Diagnostic Logs Design

Problem

After the mini program is built and uploaded, it can enter the onboarding/system initialization flow without a real login. The current startup logic treats a local access_token as proof of authentication. If the backend API is unavailable, the token is expired, or fetchUserProfile() fails, the splash page still routes to onboarding because hasProfile is false.

This makes production failures hard to diagnose because the startup path has little structured logging for environment, API target, token validation, refresh, and routing decisions.

Goals

  • Never enter onboarding or the main app unless the current session is accepted by the backend.
  • If access_token validation fails, try refresh_token once before sending the user to login.
  • Clear local tokens only when refresh/auth recovery fails or the backend explicitly rejects authentication.
  • Add production-safe console logs that show the current environment, backend API/WS configuration, auth stage, request path, response status, and route decision.
  • Keep the change scoped to mini program startup auth, request handling, and diagnostics.

Non-Goals

  • No UI redesign.
  • No backend contract changes unless an existing endpoint path is proven wrong during implementation.
  • No new routing framework or broad page refactor.

Current Findings

  • mini-program/src/pages/splash/index.vue checks uni.getStorageSync('access_token') directly. If any token exists, it calls fetchUserProfile(), then routes to main when hasProfile is true or onboarding when false.
  • mini-program/src/stores/app.js has the same pattern in initialize(): local token means isLoggedIn = true.
  • fetchUserProfile() catches errors and returns null, so the caller cannot distinguish "no profile" from "API failed" or "unauthorized".
  • mini-program/src/services/auth.js already exposes validateToken() and refreshToken().
  • mini-program/src/services/request.js logs only when DEBUG is true. Production sets VITE_DEBUG=false, so key diagnostics disappear online.

Introduce one unified session recovery flow in the app store, used by splash and protected pages:

  1. Read access_token and refresh_token.
  2. If no access_token exists, reset auth state and return unauthenticated.
  3. Validate access_token with /auth/validateToken.
  4. If validation succeeds, fetch the current profile and return authenticated.
  5. If validation fails and a refresh_token exists, call /auth/refreshToken.
  6. If refresh succeeds, save new tokens, fetch the current profile, and return authenticated.
  7. If refresh fails, clear tokens, reset auth state, and return unauthenticated.
  8. If the network/API fails in a way that is not an auth rejection, return error so splash can route to login with a visible toast or keep the user from entering onboarding.

The splash page becomes the only startup router. It should route based on the recovery result:

  • unauthenticated -> /pages/login/index
  • authenticated with profile -> /pages/main/index
  • authenticated without profile -> /pages/onboarding/index
  • error -> /pages/login/index with diagnostic toast for now

Logging Design

Add a small diagnostics helper or local logging functions that print structured logs with stable tags:

  • [ENV] at startup: normalized env, raw env, API base URL, WS URL, debug flag, platform.
  • [AUTH] restore:start: whether access/refresh token exists, using masked token presence only.
  • [AUTH] validate:success|fail
  • [AUTH] refresh:start|success|fail
  • [AUTH] profile:success|empty|fail
  • [AUTH] route: final route and reason.
  • [API] request: method, path, full URL, env.
  • [API] response: path, HTTP status, backend code, success.
  • [API] fail: path, error message.

Production logging must not print raw token values, phone numbers, SMS codes, Authorization headers, or full sensitive payloads.

Because the current production VITE_DEBUG=false hides logs, auth and environment logs should always print during startup. General request logs can remain tied to DEBUG, except auth-related request failures should always print a concise error.

Implementation Units

  • mini-program/src/config/env.js

    • Expose a stable getConfig() result for logs.
    • Keep existing API/WS selection behavior.
  • mini-program/src/services/request.js

    • Improve request/response/failure logs.
    • On HTTP 401, clear tokens and use uni.reLaunch({ url: '/pages/login/index' }).
    • Reject with enough status/code metadata for auth recovery to decide what happened.
  • mini-program/src/services/auth.js

    • Reuse validateToken() and refreshToken().
    • Ensure refresh stores returned tokens.
  • mini-program/src/stores/app.js

    • Add restoreSession() as the single startup auth API.
    • Make initialize() call restoreSession() or deprecate direct token trust.
    • Make fetchUserProfile() optionally surface errors for auth flow.
  • mini-program/src/pages/splash/index.vue

    • Replace direct token branching with store.restoreSession().
    • Route only from the returned status.
  • mini-program/src/pages/main/index.vue

    • Avoid fetching protected business data when session recovery fails.

Error Handling

  • Invalid/expired access token: attempt refresh once.
  • Missing refresh token after validation failure: clear auth and route to login.
  • Refresh 401 or backend rejection: clear auth and route to login.
  • Profile API 401: clear auth and route to login.
  • Network/API unreachable during startup: do not enter onboarding/main. Route to login with logs showing API target and failure.

Verification

  • Build mini-program for WeChat with production mode.
  • Confirm startup console prints environment and backend URL.
  • Test with no tokens: splash routes to login.
  • Test with valid tokens and existing profile: routes to main.
  • Test with valid tokens and no profile: routes to onboarding.
  • Test with expired access token and valid refresh token: refreshes, then routes correctly.
  • Test with expired access and refresh token: clears tokens and routes to login.
  • Test with backend/API unreachable: does not enter onboarding; logs request failure and route reason.