10. Testing, Debugging, and Production
Verify both providers, debug common failures, configure production secrets, and complete a security review.
Test the Complete Flow
Test signed-out navigation, invalid credentials, successful credentials login, Google login, session persistence after refresh, sign-out, disallowed users, direct API access without a session, and insufficient roles. Confirm protected APIs return 401 or 403 as appropriate. Check that secrets and tokens never appear in browser bundles or logs.
- Test direct API calls, not just visible UI.
- Verify both providers independently.
- Test denied access and sign-out.
Common Errors and Fixes
CLIENT_FETCH_ERROR: inspect /api/auth/session, the route, and base URL. Secret errors: set NEXTAUTH_SECRET in the active environment. OAuth callback failure: verify client ID/secret, exact callback URI, NEXTAUTH_URL, and proxy headers. Credentials always fail: check backend URL, request body, response status, and required user.id/user.email. Session fields missing: check both jwt and session callbacks and confirm SessionProvider wraps the app. Redirect loop: ensure the sign-in page is public.
Production Environment Variables
Set production variables in your hosting provider's secret manager. Use the canonical HTTPS app URL, a production-specific strong secret, the correct Google OAuth client, and the real backend URL. Register the exact production callback URI with Google. Redeploy after changes.
NEXTAUTH_URL=https://app.your-domain.example
NEXTAUTH_SECRET=unique_production_secret
GOOGLE_CLIENT_ID=production_client_id
GOOGLE_CLIENT_SECRET=production_client_secret
AUTH_API_URL=https://api.your-domain.exampleProduction Security Checklist
Before launch, verify HTTPS, a unique secret, exact Google redirect URIs, strong password hashing and rate limiting in the backend, generic login errors, minimal session fields, server-side authorization for every protected resource, safe redirect handling, deliberate account-linking rules, patched dependencies, and safe logging. Do not expose provider secrets, passwords, session cookies, or unnecessary OAuth tokens.
Final Mental Model
Providers authenticate; authorize handles custom Credentials verification; signIn allows or denies; jwt stores selected claims for JWT sessions; session exposes safe fields; useSession reads client session state; signIn and signOut initiate auth actions; and server-side checks protect data and operations. Keep identity verification, session state, UI behavior, and authorization separate.