How to Make a From Login to Post-Login With Database Using JavaScript

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.

Related blog posts