Skip to main content

NX Monorepo – Debug login flow with production auth

Problem to Solve

You want to log in to http://localhost:4200 using the production authentication flow
inside an NX monorepo setup, without mocking auth or bypassing guards.

Context / Keywords

  • NX monorepo
  • Angular frontend
  • NestJS AuthGuard
  • JWT login via URL
  • Debugging using browser
  • Production auth in local environment

Expected Behavior

When accessing the local frontend with a valid production login token:


[http://localhost:4200/decrypt?login=](http://localhost:4200/decrypt?login=)<JWT>&path=/admin

The application should:

  1. Consume the login token
  2. Authenticate the user
  3. Redirect to:

[http://localhost:4200/admin](http://localhost:4200/admin)


Actual Behavior (Problem)

Instead of a single redirect, the application keeps redirecting and repeating the login token inside the path parameter, producing URLs like:


[http://localhost:4200/decrypt?login=](http://localhost:4200/decrypt?login=)<JWT>&path=/admin?login=<JWT>,/admin?login=<JWT>,/admin?

This results in:

  • Exponentially growing URLs
  • Redirect loops
  • Inability to reach /admin

Reproduction Steps

  1. Open a normal browser window
  2. Navigate to:

[http://localhost:4200/decrypt?login=](http://localhost:4200/decrypt?login=)<JWT>&path=/admin

  1. Observe repeated redirects and URL growth

Temporary Workaround (What Actually Works)

✅ Open an Incognito / Private window


[http://localhost:4200](http://localhost:4200)

➡️ The application successfully redirects to:


[http://localhost:4200/admin](http://localhost:4200/admin)


Why Incognito Works

Incognito mode starts with a clean browser state.

In a normal browser window, the following values may persist between attempts:

  • setEncryptedToken
  • saveUser
  • applicationOrigin
  • stored redirect path
  • loginAs / login-related query params

Because of this, AuthGuard is triggered multiple times with polluted state, causing the same URL (including login) to be repeatedly appended to path.

In Incognito:

  • No localStorage
  • No sessionStorage
  • No cookies
  • No previous redirect state

➡️ AuthGuard executes once with a clean state, and the flow completes correctly.


Root Cause Analysis

This issue is not a browser bug.

The real causes are:

  1. AuthGuard performs login side effects
    • Token verification
    • User persistence
    • Redirect logic
  2. URL parameters (login, path) are not cleaned after consumption
  3. state.url (including query params) is reused as a redirect path
  4. AuthGuard is executed again before the URL is cleaned, causing redirect loops

In short:

AuthGuard mixes authentication checking and login execution, which leads to repeated redirects when using JWT login via URL.


Code Review (Relevant Parts)

Routing logic for production environment

page routing logic

AuthGuard implementation

auth guard

Global login URL configuration

global url


Key Takeaways

  • AuthGuard should only decide access, not perform login
  • Login tokens passed via URL must be consumed once and removed
  • Redirect paths must never include login-related query parameters
  • Incognito success indicates state pollution, not token issues

  • Move login/token consumption to a dedicated DecryptComponent
  • Keep AuthGuard responsible only for:
    • isAuthenticated
    • isTokenValid
  • Clean URLs using replaceUrl: true after login
  • Avoid using full state.url (with query params) as redirect path

Summary

Using production authentication inside a local NX monorepo environment can expose hidden redirect and guard execution issues.

The infinite redirect loop was caused by AuthGuard handling login logic combined with uncleaned URL parameters, not by JWT or browser behavior.

Incognito mode worked because it reset all persisted authentication state.