Today, I’m going to walk you through how I built a user authentication system for a web application with database using JavaScript. This includes connecting the login route, logout route, adding styling, ensuring users are logged in after signing up, and redirecting them to a post-login page. If you’re a developer looking to implement a smooth authentication flow, this is for you. Let’s dive in!
Setting Up the Login Route
First things first, I needed to create a login route that allows users to authenticate themselves. Here’s how I did it:
Backend (Node.js + Express)
I used Express to handle routing and Passport.js for authentication. Here’s a snippet of the login route:
const express = require('express'); const passport = require('passport'); const router = express.Router(); // Login route router.post('/login', (req, res, next) => { passport.authenticate('local', (err, user, info) => { if (err) throw err; if (!user) res.status(401).send(info.message); // User not found or incorrect credentials else { req.logIn(user, (err) => { if (err) throw err; res.status(200).send('Logged in successfully!'); }); } })(req, res, next); }); module.exports = router;
Frontend (React)
On the frontend, I created a login form that sends a POST request to the /login
route:
const handleLogin = async (e) => { e.preventDefault(); const response = await fetch('/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }), }); const data = await response.text(); if (response.status === 200) { // Redirect to post-login page window.location.href = '/dashboard'; } else { alert(data); // Show error message } };
Connecting the Logout Route
Next, I implemented the logout functionality. This is crucial for user security and session management.
Backend
The logout route is simple. It destroys the user’s session:
router.get('/logout', (req, res) => { req.logout((err) => { if (err) throw err; res.status(200).send('Logged out successfully!'); }); });
Frontend
On the frontend, I added a logout button that calls this route:
const handleLogout = async () => { const response = await fetch('/logout'); const data = await response.text(); if (response.status === 200) { window.location.href = '/'; // Redirect to home page } };
Adding Styling
Aesthetics matter! I used Tailwind CSS to style the login and signup forms. Here’s a quick example of the login form:
<div className="flex items-center justify-center min-h-screen bg-gray-100"> <div className="bg-white p-8 rounded-lg shadow-md w-96"> <h2 className="text-2xl font-bold mb-6 text-center">Login</h2> <form onSubmit={handleLogin}> <input type="text" placeholder="Username" className="w-full p-2 mb-4 border rounded" value={username} onChange={(e) => setUsername(e.target.value)} /> <input type="password" placeholder="Password" className="w-full p-2 mb-4 border rounded" value={password} onChange={(e) => setPassword(e.target.value)} /> <button type="submit" className="w-full bg-blue-500 text-white p-2 rounded hover:bg-blue-600" > Login </button> </form> </div> </div>
Run HTML
Logging In After Signup
To improve user experience, I ensured that users are automatically logged in after signing up. Here’s how I did it:
Backend
After creating a new user in the database, I logged them in:
router.post('/signup', async (req, res) => { const { username, password } = req.body; const newUser = new User({ username, password }); await newUser.save(); // Automatically log in the user req.logIn(newUser, (err) => { if (err) throw err; res.status(200).send('Signed up and logged in successfully!'); }); });
Frontend
On the frontend, I redirected the user to the dashboard after signup:
const handleSignup = async (e) => { e.preventDefault(); const response = await fetch('/signup', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }), }); const data = await response.text(); if (response.status === 200) { window.location.href = '/dashboard'; // Redirect to dashboard } else { alert(data); // Show error message } };
Post-Login Page
After logging in, users are redirected to a post-login page (e.g., a dashboard). Here’s how I implemented it:
Backend
I added middleware to check if the user is authenticated before allowing access to the dashboard:
const isAuthenticated = (req, res, next) => { if (req.isAuthenticated()) return next(); res.status(401).send('Unauthorized'); }; router.get('/dashboard', isAuthenticated, (req, res) => { res.status(200).send(`Welcome, ${req.user.username}!`); });
Frontend
The dashboard page fetches user data and displays it:
const Dashboard = () => { const [user, setUser] = useState(null); useEffect(() => { fetch('/dashboard') .then((res) => res.text()) .then((data) => setUser(data)) .catch((err) => console.error(err)); }, []); return ( <div className="p-8"> <h1 className="text-3xl font-bold">{user}</h1> <button onClick={handleLogout} className="mt-4 bg-red-500 text-white p-2 rounded hover:bg-red-600"> Logout </button> </div> ); };
Final Thoughts
Building a user authentication system can seem daunting at first, but breaking it down into smaller steps makes it manageable. By connecting the login and logout routes, adding styling, ensuring users are logged in after signing up, and creating a post-login page, I was able to create a seamless user experience.