This page covers the frontend authentication system: the AuthContext React context, the AuthProvider component, cookie-based token storage, the API key state, and the route guard components that restrict access. For information about the backend JWT implementation and refresh token handling, see Authentication and Security. For the Axios interceptor layer that handles automatic token refresh on HTTP 401/403 responses, see API Client Layer.
The frontend auth system has two layers:
AuthContext — A React context that holds user identity state (accessToken, userData, apiKey) and exposes login, clearAuthSession, and getUser to any component that needs them.ApiInterceptor — A component that registers Axios and fetch interceptors to transparently retry failed requests after refreshing the access token.Both layers read from and write to useAuthStore (a Zustand store), which acts as the source of truth for the isAuthenticated and isAdmin flags consumed by the route guards.
Defined in src/frontend/src/types/contexts/auth.ts1-18
| Field | Type | Purpose |
|---|---|---|
accessToken | string | null | Current JWT access token held in component state |
login | (accessToken, autoLogin, refreshToken?) => void | Stores tokens in cookies/localStorage and loads user data |
userData | Users | null | Profile object returned from /api/v1/users/whoami |
setUserData | (Users | null) => void | Allows manual replacement of the user profile |
authenticationErrorCount | number | Tracks consecutive auth failures (hardcoded to 0 in provider value; actual tracking lives in useAuthStore) |
apiKey | string | null | Langflow API key (used for Store page access) |
setApiKey | (string | null) => void | Directly replaces the API key state |
storeApiKey | (string) => void | Alias that calls setApiKey |
getUser | () => void | Fetches and refreshes userData from the backend |
clearAuthSession | () => void | Wipes all tokens and resets auth state |
Sources: src/frontend/src/types/contexts/auth.ts1-18
AuthProvider is defined in src/frontend/src/contexts/authContext.tsx32-161 and wraps the entire application via ContextWrapper.
accessToken — string | null (React state)
userData — Users | null (React state)
apiKey — string | null (React state)
External state (useAuthStore, useStoreStore) is accessed via Zustand hooks, not React context.
AuthProvider: Data Sources and Consumers
Sources: src/frontend/src/contexts/authContext.tsx32-161 src/frontend/src/pages/AdminPage/LoginPage/index.tsx1-84 src/frontend/src/pages/StorePage/index.tsx53 src/frontend/src/pages/AdminPage/index.tsx54
The login function uses two storage mechanisms in parallel:
| Storage | Keys Written | Notes |
|---|---|---|
| Cookies | LANGFLOW_ACCESS_TOKEN, LANGFLOW_AUTO_LOGIN_OPTION, LANGFLOW_REFRESH_TOKEN | Written via cookieManager.set(); HttpOnly cookies set by the server are handled separately |
localStorage | LANGFLOW_ACCESS_TOKEN | Written via setLocalStorage() |
The clearAuthSession function removes all of these:
cookieManager.clearAuthCookies() — clears all auth cookieslocalStorage.removeItem(LANGFLOW_ACCESS_TOKEN)localStorage.removeItem(LANGFLOW_API_TOKEN)localStorage.removeItem(LANGFLOW_REFRESH_TOKEN)Sources: src/frontend/src/contexts/authContext.tsx67-140
login() sequence
Sources: src/frontend/src/contexts/authContext.tsx67-125
clearAuthSession() sequence
Sources: src/frontend/src/contexts/authContext.tsx131-140
apiKey in AuthContext holds a Langflow-issued API token (separate from the JWT access token). It is used by pages like StorePage to authenticate against the component marketplace.
storeApiKey(apiKey: string) which calls setApiKey(apiKey).useContext(AuthContext).apiKey.clearAuthSession().The StorePage reads apiKey from context and re-triggers its component fetch whenever apiKey changes:
src/frontend/src/pages/StorePage/index.tsx53 src/frontend/src/pages/StorePage/index.tsx91-106
Route guards are React components that wrap route elements and redirect unauthenticated or unauthorized users. They are registered in routes.tsx.
Route Guard Hierarchy
| Guard Component | File | Behaviour |
|---|---|---|
ProtectedRoute | components/authorization/authGuard | Redirects to /login if not authenticated |
ProtectedAdminRoute | components/authorization/authAdminGuard | Redirects if useAuthStore.isAdmin is false |
ProtectedLoginRoute | components/authorization/authLoginGuard | Redirects away from login if already authenticated |
AuthSettingsGuard | components/authorization/authSettingsGuard | Guards specific settings sub-routes |
Sources: src/frontend/src/routes.tsx8-11 src/frontend/src/routes.tsx70-215
ApiInterceptor is a React component (renders null) defined in src/frontend/src/controllers/API/api.tsx29-243 that registers Axios and fetch interceptors inside a useEffect.
| Interceptor | Trigger | Action |
|---|---|---|
| Axios response (error path) | HTTP 401 or 403 | Calls mutationRenewAccessToken; on success, retries the original request |
| Axios response (error path) | Error count > 3 | Resets counter, calls mutationLogout |
| Axios request | Every same-origin request | Adds custom headers from useCustomApiHeaders() |
fetch intercept | Every non-external fetch | Adds custom headers |
authenticationErrorCount (from useAuthStore)
increment on each 401/403
if > 3 → setAuthenticationErrorCount(0) → mutationLogout()
on successful token refresh → setAuthenticationErrorCount(0)
The IS_AUTO_LOGIN constant gates whether refresh is attempted at all:
src/frontend/src/controllers/API/api.tsx74-78
Sources: src/frontend/src/controllers/API/api.tsx65-240
AuthContext and useAuthStore are complementary, not redundant:
| Concern | Lives In |
|---|---|
accessToken (React state) | AuthContext |
userData (user profile object) | AuthContext |
apiKey (Store API key) | AuthContext |
isAuthenticated flag | useAuthStore (Zustand) |
isAdmin flag | useAuthStore (Zustand) |
autoLogin flag | useAuthStore (Zustand) |
authenticationErrorCount | useAuthStore (Zustand) |
AuthContext writes to useAuthStore (via setIsAuthenticated, setIsAdmin) but does not read from it directly. Route guards and ApiInterceptor read from useAuthStore directly without going through AuthContext.
Sources: src/frontend/src/contexts/authContext.tsx40-41 src/frontend/src/controllers/API/api.tsx30-42
LoginAdminPage src/frontend/src/pages/AdminPage/LoginPage/index.tsx17-84 demonstrates the canonical usage pattern:
login from useContext(AuthContext).useLoginUser() mutation (React Query).login(res.access_token, "login", res.refresh_token).This pattern is the same for the regular LoginPage. The login() call in AuthProvider then handles all downstream token storage and user-data fetching.
Sources: src/frontend/src/pages/AdminPage/LoginPage/index.tsx20-50
Refresh this wiki
This wiki was recently refreshed. Please wait 3 days to refresh again.