A social knowledge tool for researchers built on ATProto
Using React with the Current Authentication Setup#
This document outlines considerations and patterns for integrating a React frontend with the existing Express backend's authentication system, which relies on iron-session and HttpOnly cookies.
Core Principles:#
-
HttpOnlyCookies Remain Server-Managed:- The
HttpOnlysession cookie (e.g.,sid) set by the backend will continue to be the primary mechanism for session persistence. - The browser will automatically send this cookie with API requests to the backend.
- React client-side code cannot and should not attempt to directly access or manipulate this
HttpOnlycookie.
- The
-
Client-Side Authentication State:
- While the browser handles the cookie, the React application needs its own internal state to know if a user is authenticated and who the user is. This state will drive UI changes (e.g., showing user-specific content, login/logout buttons).
Recommended Patterns:#
-
Dedicated API Endpoint for User Data (
/api/me):- Create a new backend endpoint (e.g.,
/api/me). - This endpoint should use the existing
getSessionAgentlogic (or similar) to check for a valid session cookie. - If authenticated, it should return relevant user information (e.g., DID, display name, profile details).
- If not authenticated, it should return an appropriate error (e.g., 401 Unauthorized).
- Create a new backend endpoint (e.g.,
-
Fetching User Data on App Load:
- When the React app initializes, it should make a request to the
/api/meendpoint. - Based on the response, the React app updates its internal authentication state (e.g., in React Context, Redux, Zustand, or component state).
- When the React app initializes, it should make a request to the
-
Login Flow:
- The React app's login button/action should redirect the browser to the backend's existing
/loginroute (e.g.,window.location.href = '/login'). - The backend handles the entire OAuth flow and sets the
HttpOnlysession cookie upon successful authentication. - After the OAuth callback, the backend should redirect the user back to the React application (e.g., to the main page or a specific post-login page).
- Upon returning to the React app, it can either re-fetch from
/api/meor the backend redirect could include a signal for the app to know the login was successful, prompting a fetch to/api/me.
- The React app's login button/action should redirect the browser to the backend's existing
-
Logout Flow:
- The React app's logout button/action should make an API call (e.g.,
POST) to the backend's existing/logoutroute. - The backend destroys the
iron-session, clearing theHttpOnlycookie. - Upon a successful response from the logout API, the React app should clear its internal authentication state and update the UI.
- The React app's logout button/action should make an API call (e.g.,
-
Authenticated API Calls from React:
- When making other API calls to protected backend routes (e.g., posting a status), React's
fetchoraxioscalls will automatically include theHttpOnlysession cookie if the requests are to the same domain (or if CORS andcredentials: 'include'are correctly configured for cross-domain scenarios). - No special handling is needed in the React code to attach the session cookie itself.
- When making other API calls to protected backend routes (e.g., posting a status), React's
-
UI Updates:
- The React app uses its internal authentication state to conditionally render UI elements:
- Show user profile / logout button if authenticated.
- Show login button if not authenticated.
- Enable/disable features based on authentication status.
- The React app uses its internal authentication state to conditionally render UI elements:
Example Workflow:#
- User opens React App:
- React app calls
GET /api/me. - Browser automatically sends
sidcookie if present. - Backend validates cookie:
- If valid: Returns user data (e.g.,
{ did: '...', displayName: '...' }). React app setsuserstate. - If invalid/missing: Returns 401. React app sets
userstate tonull.
- If valid: Returns user data (e.g.,
- React app calls
- User clicks "Login":
- React app redirects to
GET /loginon the backend. - Backend initiates OAuth, user authenticates with PDS.
- Backend's
/oauth/callbackreceives PDS response, createsiron-session, setssidcookie. - Backend redirects back to React app (e.g.,
https://your-react-app.com/). - React app (on load or via a specific effect) calls
GET /api/meagain, gets user data, updates UI.
- React app redirects to
- User clicks "Post Status":
- React app makes
POST /statusrequest to backend with status data. - Browser automatically sends
sidcookie. - Backend's
/statusroute usesgetSessionAgentto validate session and process the request.
- React app makes
- User clicks "Logout":
- React app calls
POST /logouton the backend. - Backend destroys
iron-session, clearing thesidcookie. - React app clears its local
userstate, updates UI.
- React app calls
This approach leverages the security of HttpOnly cookies managed by the server while allowing the React SPA to maintain its own awareness of the authentication state for a responsive user experience.