Authentication library with HTTP-only cookies and Page Visibility API for handling sleep/wake cycles
npm install react-cookie-auth
A secure authentication library for React applications that implements HTTP-only cookie-based authentication with automatic token refresh, Page Visibility API integration, and Redux state management.
- Key Features
- Installation
- Quick Start
- Configuration
- Components
- API Reference
- Security Benefits
- Comparison with Other Solutions
- Advanced Usage
- Troubleshooting
- Storybook
- License
- Secure Authentication: HTTP-only cookie-based auth that mitigates XSS attacks
- Complete Flow: Login, logout, and token refresh functionality out of the box
- Sleep/Wake Protection: Page Visibility API integration prevents refresh token storms
- State Management: Redux integration with useful selectors and actions
- UI Components: Ready-to-use auth modals with customization options
- Developer Experience: TypeScript support and comprehensive documentation
``bash`
npm install react-cookie-auth
`jsx
import { Auth, AuthModal, LogoutModal, initAuth } from 'react-cookie-auth';
import React from 'react';
import { Provider } from 'react-redux';
// Step 1: Initialize the auth library with your API endpoints
const { store, hooks, actions, selectors } = initAuth({
apiBaseUrl: 'https://api.example.com',
loginEndpoint: '/auth/login/', // Your login endpoint
refreshTokenEndpoint: '/auth/token/refresh/', // Token refresh endpoint
logoutEndpoint: '/auth/logout/', // Logout endpoint
refreshTokenInterval: 15 60 1000, // Refresh every 15 minutes
maxRetryAttempts: 3, // Max retry attempts on failure
retryDelay: 1000, // Delay between retries
onLoginSuccess: user => console.log('User logged in', user),
onLogoutSuccess: () => console.log('User logged out'),
onAuthError: error => console.error('Auth error', error),
});
// Step 2: Use in your app component
function App() {
// Extract hooks for auth operations
const { useRefreshToken, useLoginMutation, useLogoutMutation } = hooks;
const [loginMutation] = useLoginMutation();
const [logoutMutation] = useLogoutMutation();
const [refreshTokenMutation] = useRefreshTokenMutation();
// Create the refresh function using the hook
const refreshFunction = useRefreshToken(refreshTokenMutation);
return (
{/ Step 3: Add Auth wrapper to manage token refresh /}
refreshInterval={15 60 1000}
onAuthStateChange={isLoggedIn => console.log('Auth state changed', isLoggedIn)}
>
{/ Step 4: Use auth modals where needed /}
onClose={() => setShowLoginModal(false)}
onSubmit={credentials => loginMutation(credentials)}
config={{
title: 'Login to Your Account',
submitButtonText: 'Login',
}}
/>
onClose={() => setShowLogoutModal(false)}
onLogout={() => logoutMutation()}
config={{
title: 'Logout',
message: 'Are you sure you want to logout?',
confirmButtonText: 'Yes, logout',
cancelButtonText: 'Cancel',
}}
/>
{/ Your app content /}
);
}
`
The initAuth function accepts the following configuration options:
| Option | Type | Description |
| -------------------- | -------- | -------------------------------------------------- |
| apiBaseUrl | string | Base URL for API requests |
| loginEndpoint | string | Endpoint for login requests |
| refreshTokenEndpoint | string | Endpoint for refresh token requests |
| logoutEndpoint | string | Endpoint for logout requests |
| refreshTokenInterval | number | Interval in milliseconds between token refreshes |
| maxRetryAttempts | number | Maximum number of retry attempts for token refresh |
| retryDelay | number | Delay between retry attempts in milliseconds |
| onLoginSuccess | function | Callback function when login is successful |
| onLogoutSuccess | function | Callback function when logout is successful |
| onAuthError | function | Callback function when auth error occurs |
The main authentication component that handles token refresh logic and Page Visibility API integration.
`jsx`
refreshInterval={refreshInterval} // How often to refresh (ms)
onAuthStateChange={handleAuthStateChange} // Called when auth state changes
invalidateAuthTags={invalidateTags} // Optional: refresh cached data
>
{children}
A modal component for login/signup forms.
`jsx`
onClose={handleClose} // Called when modal is closed
onSubmit={handleSubmit} // Called with form data on submit
config={{
// Customize appearance
title: 'Login',
submitButtonText: 'Submit',
}}
/>
A modal component for confirming logout actions.
`jsx`
onClose={handleClose} // Called when modal is closed
onLogout={handleLogout} // Called when logout is confirmed
config={{
// Customize appearance
title: 'Logout',
message: 'Are you sure?',
confirmButtonText: 'Yes',
cancelButtonText: 'No',
}}
/>
- useRefreshToken: Creates a function to refresh the authentication tokenuseLoginMutation
- : RTK Query hook for login requestsuseLogoutMutation
- : RTK Query hook for logout requestsuseRefreshTokenMutation
- : RTK Query hook for refresh token requests
- setUser: Redux action to set the current user in the store
- isAuthenticated: Selector to check if the user is authenticatedgetUser
- : Selector to get the current user from the store
- HTTP-Only Cookies: Prevents JavaScript from accessing authentication tokens, protecting against XSS attacks
- Automatic Token Refresh: Maintains authentication state securely without user intervention
- Page Visibility Handling: Prevents refresh token storms after device sleep/wake cycles
- Secure State Management: Integrates with Redux for predictable state management
- No Local Storage: Avoids storing sensitive auth information in vulnerable browser storage
| Feature | react-cookie-auth | JWT in localStorage | Auth0/Okta |
| ------------------------- | ----------------- | ------------------- | ----------- |
| XSS Protection | ✅ High | ❌ Low | ✅ High |
| Automatic Token Refresh | ✅ Built-in | ⚠️ Manual | ✅ Built-in |
| Sleep/Wake Cycle Handling | ✅ Built-in | ❌ None | ⚠️ Varies |
| Implementation Complexity | Medium | Low | High |
| External Service Required | ❌ No | ❌ No | ✅ Yes |
You can create custom authentication components by using the hooks and actions provided by the library:
`jsx
import { initAuth } from 'react-cookie-auth';
import { useSelector } from 'react-redux';
const { hooks, actions, selectors } = initAuth({
// configuration
});
function CustomLoginForm() {
const [loginMutation, { isLoading, error }] = hooks.useLoginMutation();
const handleSubmit = async event => {
event.preventDefault();
const username = event.target.username.value;
const password = event.target.password.value;
try {
await loginMutation({ username, password }).unwrap();
} catch (error) {
console.error('Login failed', error);
}
};
return (
Troubleshooting
$3
- Token Not Refreshing: Ensure your backend supports the refresh token endpoint and returns proper HTTP-only cookies.
- Authentication State Lost: Check if
SameSite and Secure attributes are set correctly on your cookies.- CORS Issues: Your backend needs to allow credentials and have proper CORS headers set.
`
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://yourdomain.com
`- Redux Integration: If using with existing Redux store, make sure to properly combine the auth reducer with your application's reducers.
Storybook
This library includes a Storybook setup to showcase and document the components.
$3
`bash
npm run storybook
`This will launch Storybook on http://localhost:6006 where you can browse and interact with all the components.
$3
- Auth: Authentication wrapper component with different configurations
- AuthModal: Login form modal with various states and styling options
- LogoutModal: Logout confirmation modal with different configurations
$3
To build a static version of Storybook for deployment:
`bash
npm run build-storybook
``MIT