115 lines
6.1 KiB
Markdown
115 lines
6.1 KiB
Markdown
# 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.
|
|
|
|
## Recommended Approach
|
|
|
|
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.
|
|
|