To create an authentication system using React.js on the frontend, Express.js on the backend we need to implement the following:
Let's start with the backend to handle user authentication and token generation.
npm install express bcryptjs jsonwebtoken cors
Create an authController.js file to handle authentication logic:
// authController.js const bcrypt = require('bcryptjs'); const jwt = require('jsonwebtoken'); // Mock user data (in production, you would use a real database) const users = [ { id: 1, username: 'john', password: '$2a$10$O1s8iLKRLPbPqhc1uTquLO.xODTC1U/Z8xGoEDU6/Dc0PAQ3MkCKy', // hashed password for 'password123' }, ]; // JWT Secret const JWT_SECRET = 'supersecretkey'; exports.login = (req, res) => { const { username, password } = req.body; const user = users.find((u) => u.username === username); if (!user) { return res.status(401).json({ error: 'Invalid credentials' }); } bcrypt.compare(password, user.password, (err, isMatch) => { if (isMatch) { // Create a token const token = jwt.sign({ id: user.id, username: user.username }, JWT_SECRET, { expiresIn: '1h' }); return res.json({ token }); } else { return res.status(401).json({ error: 'Invalid credentials' }); } }); }; exports.validateToken = (req, res) => { const token = req.header('Authorization').replace('Bearer ', ''); if (!token) { return res.status(401).json({ error: 'No token provided' }); } try { const decoded = jwt.verify(token, JWT_SECRET); res.json({ user: { id: decoded.id, username: decoded.username } }); } catch (err) { res.status(401).json({ error: 'Invalid token' }); } };
Next, create the main server.js file for setting up Express:
// server.js const express = require('express'); const cors = require('cors'); const { login, validateToken } = require('./authController'); const app = express(); app.use(express.json()); app.use(cors()); // Authentication routes app.post('/api/login', login); app.get('/api/validate', validateToken); // Start the server const PORT = 5000; app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); });
Now let's set up the frontend using React.js and Pulsy to handle the authentication state.
npm install axios pulsy
We will create a Pulsy store to manage authentication state globally.
// authStore.js import { createStore, addMiddleware } from 'pulsy'; import axios from 'axios'; // Create a store to hold the user and token createStore('auth', { user: null, token: null, }, { persist: true }); // Persist the auth state in localStorage // Middleware to add Authorization header for authenticated requests addMiddleware('auth', (nextValue, prevValue, storeName) => { if (nextValue.token) { axios.defaults.headers.common['Authorization'] = `Bearer ${nextValue.token}`; } else { delete axios.defaults.headers.common['Authorization']; } return nextValue; });
This store will persist the authentication state (user and token) and automatically apply the Authorization header for authenticated requests.
Create helper functions to handle login and validation requests:
// authService.js import { setStoreValue } from 'pulsy'; import axios from 'axios'; const API_URL = 'http://localhost:5000/api'; export const login = async (username, password) => { try { const response = await axios.post(`${API_URL}/login`, { username, password }); const { token } = response.data; // Set token and user info in Pulsy store setStoreValue('auth', { token, user: { username } }); return true; } catch (error) { console.error('Login failed', error); return false; } }; export const validateToken = async () => { try { const response = await axios.get(`${API_URL}/validate`); const user = response.data.user; // Update the store with the user info setStoreValue('auth', { user, token: localStorage.getItem('auth_token') }); return true; } catch (error) { console.error('Token validation failed', error); return false; } }; export const logout = () => { setStoreValue('auth', { user: null, token: null }); localStorage.removeItem('pulsy_auth'); };
Now let’s create the React components for login and authenticated views.
// Login.js import React, { useState } from 'react'; import { login } from './authService'; const Login = () => { const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(''); const handleLogin = async (e) => { e.preventDefault(); const success = await login(username, password); if (!success) { setError('Invalid credentials. Try again.'); } }; return ( <div> <h2>Login</h2> <form onSubmit={handleLogin}> <input type="text" value={username} onChange={(e) => setUsername(e.target.value)} placeholder="Username" required /> <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="Password" required /> <button type="submit">Login</button> </form> {error && <p style={{ color: 'red' }}>{error}</p>} </div> ); }; export default Login;
// Dashboard.js import React from 'react'; import { usePulsy } from 'pulsy'; import { logout } from './authService'; const Dashboard = () => { const [auth] = usePulsy('auth'); const handleLogout = () => { logout(); window.location.reload(); // Simple page refresh to redirect to login }; return ( <div> <h2>Welcome, {auth.user.username}!</h2> <button onClick={handleLogout}>Logout</button> </div> ); }; export default Dashboard;
In the App.js component, you’ll want to check if the user is authenticated and conditionally render either the login or dashboard.
// App.js import React, { useEffect } from 'react'; import { usePulsy } from 'pulsy'; import { validateToken } from './authService'; import Login from './Login'; import Dashboard from './Dashboard'; function App() { const [auth] = usePulsy('auth'); useEffect(() => { // Check token validity on app load if (auth.token) { validateToken(); } }, [auth.token]); return ( <div className="App"> {auth.user ? <Dashboard /> : <Login />} </div> ); } export default App;
Now that we have both the backend and frontend set up, you can run the application.
node server.js
npm start
Once both are running:
This example shows how to integrate Pulsy with a React authentication system backed by an Express.js API. Pulsy helps you manage global state for authentication, including persistence of the authentication token and user data across sessions, making it a powerful and easy-to-use state management tool.
Atas ialah kandungan terperinci Pengesahan dengan express js dan react js unsing jwt. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!