A lightweight authentication package for Express/React applications that provides single-password protection with session management.
- 🔐 Single Password Authentication - Perfect for internal tools and admin panels
- 🍪 Cookie-based Sessions - Uses cookie-session for stateless sessions (no server storage needed)
- ⚛️ React Components - Ready-to-use components for login forms and protected routes
- 🛡️ Express Middleware - Easy route protection with middleware functions
- 🎨 Customizable - Flexible styling and configuration options
- 📦 Lightweight - Minimal dependencies, maximum functionality
- 🆕 Modern - Supports Express 5+, React 19+, bcrypt 6+
npm install simple-express-react-auth
const express = require('express');
const cookieSession = require('cookie-session');
const { expressAuth } = require('simple-express-react-auth');
const app = express();
// Session middleware (required)
app.use(cookieSession({
name: 'session',
keys: ['your-secret-key'], // Use multiple keys for key rotation
maxAge: 24 * 60 * 60 * 1000 // 24 hours
}));
app.use(express.json());
// Create auth system
const { router, requireAuth } = expressAuth.createAuth({
password: 'your-secret-password'
});
// Add auth routes
app.use('/auth', router);
// Protect your routes
app.get('/protected', requireAuth, (req, res) => {
res.json({ message: 'This is protected!' });
});
app.listen(3000);
import React from 'react';
import { AuthProvider, ProtectedRoute, LogoutButton } from 'simple-express-react-auth/react';
function App() {
return (
<AuthProvider apiBaseUrl="http://localhost:3000">
<div>
<h1>My Protected App</h1>
<ProtectedRoute>
<div>
<p>Welcome! You are authenticated.</p>
<LogoutButton />
</div>
</ProtectedRoute>
</div>
</AuthProvider>
);
}
export default App;
Creates authentication router and middleware.
Options:
-
password
(string) - Plain text password to hash and use for auth -
hashedPassword
(string) - Pre-hashed password (alternative topassword
) -
loginPath
(string) - Login endpoint path relative to router mount (default:/login
) -
logoutPath
(string) - Logout endpoint path relative to router mount (default:/logout
) -
statusPath
(string) - Status endpoint path relative to router mount (default:/status
) -
saltRounds
(number) - BCrypt salt rounds (default: 12)
Returns:
-
router
- Express router with auth endpoints -
requireAuth
- Middleware for API route protection -
requireAuthRedirect
- Middleware for HTML route protection with redirect
-
POST /auth/login
- Login with password -
GET /auth/logout
- Logout and clear session -
GET /auth/status
- Check authentication status
Context provider for authentication state.
Props:
-
apiBaseUrl
(string) - Base URL for auth API calls (default: '') -
statusPath
(string) - Status endpoint path (default: '/auth/status') -
loginPath
(string) - Login endpoint path (default: '/auth/login') -
logoutPath
(string) - Logout endpoint path (default: '/auth/logout')
Hook to access authentication state and methods.
Returns:
-
isAuthenticated
(boolean) - Current auth status -
isLoading
(boolean) - Loading state -
error
(string|null) - Current error message -
login(password)
- Login function -
logout()
- Logout function -
checkAuthStatus()
- Refresh auth status
Component that conditionally renders children based on auth status.
Props:
-
children
- Content to render when authenticated -
fallback
- Custom component to render when not authenticated -
loadingComponent
- Custom loading component -
className
- CSS class name
Ready-to-use login form component.
Props:
-
onLoginSuccess
- Callback function on successful login -
className
- CSS class name -
submitButtonText
- Button text (default: 'Login') -
passwordPlaceholder
- Input placeholder (default: 'Enter password') -
showError
- Show error messages (default: true)
Button component for logging out.
Props:
-
children
- Button content (default: 'Logout') -
onLogoutSuccess
- Callback function on successful logout -
className
- CSS class name - Plus any other button props
import { LoginForm } from 'simple-express-react-auth/react';
function CustomLogin() {
return (
<div className="my-login-container">
<LoginForm
className="my-login-form"
submitButtonText="Sign In"
passwordPlaceholder="Enter your password"
onLoginSuccess={() => console.log('Logged in!')}
/>
</div>
);
}
const { requireAuthRedirect } = expressAuth.createAuth({
password: 'secret'
});
// Redirect to custom login page
app.get('/admin', requireAuthRedirect('/custom-login'), (req, res) => {
res.send('Admin panel');
});
const bcrypt = require('bcrypt');
async function setupAuth() {
const hashedPassword = await bcrypt.hash('my-password', 12); // Updated to use higher salt rounds
const { router, requireAuth } = expressAuth.createAuth({
hashedPassword: hashedPassword
});
return { router, requireAuth };
}
function CustomProtectedRoute({ children }) {
return (
<ProtectedRoute
fallback={
<div className="custom-login">
<h2>Access Restricted</h2>
<LoginForm submitButtonText="Access System" />
</div>
}
>
{children}
</ProtectedRoute>
);
}
- Node.js 16+
- Express 4+ or 5+
- React 16.8+ (for hooks)
- cookie-session (or compatible session middleware)
- Always use HTTPS in production
- Use strong session secrets/keys
- Consider session configuration (secure cookies, etc.)
- This package uses
cookie-session
for stateless sessions - no server-side storage required - This package is designed for internal tools, not public-facing authentication
ISC
Contributions welcome! Please read the contributing guidelines and submit pull requests to the main repository.