You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js登录鉴权API前后端对接及错误信息展示问题咨询

Hey there! Let's work through your two questions step by step, since you're using Express/EJS which has some specific patterns for this stuff:

1. What should I put in the form's action attribute?

Looking at your backend routes, your login API endpoint is /api/user/login (from user.routes.js where you have router.post("/login", authController.signIn); and this router is mounted at /api/user in server.js).

So update your form's action to that path:

<form action="/api/user/login" method="POST">
  <!-- rest of your form fields -->
</form>

This tells the browser to send the form data directly to your login API endpoint when the user submits the form.

2. How to show backend validation errors on the frontend?

Right now your backend returns a JSON object with errors when login fails, but since you're using traditional form submission (page reloads), that JSON won't show up in your EJS template. Here are two solid approaches for your stack:

Option 1: Use Flash Messages (traditional page reload flow)

This is the most straightforward fit for EJS/Express:

  1. First install required packages:
    npm install express-session connect-flash
    
  2. Update your server.js to set up sessions and flash messages:
    const session = require('express-session');
    const flash = require('connect-flash');
    
    // Add these lines before mounting your routes
    app.use(session({
      secret: process.env.SESSION_SECRET, // Add this to your .env file (use a random string)
      resave: false,
      saveUninitialized: false
    }));
    app.use(flash());
    
    // Pass flash messages to all EJS templates automatically
    app.use((req, res, next) => {
      res.locals.loginErrors = req.flash('loginErrors');
      next();
    });
    
  3. Modify the signIn method in authController.js to flash errors instead of sending JSON:
    module.exports.signIn = async (req, res) => {
      const { email, password } = req.body;
      try {
        // ... your existing login logic
      } catch (err) {
        const errors = signInErrors(err);
        req.flash('loginErrors', errors); // Store errors in flash
        res.redirect('/'); // Send user back to login page
      }
    };
    
  4. Update your login.ejs template to display the errors:
    <% if (loginErrors && Object.keys(loginErrors).length > 0) { %>
    <div class="alert alert-warning alert-dismissible fade show" role="alert">
      <% for (const errorMsg of Object.values(loginErrors)) { %>
        <p><%= errorMsg %></p>
      <% } %>
      <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
    </div>
    <% } %>
    

Option 2: Use AJAX (no page reload, modern flow)

If you want to avoid page reloads, use JavaScript to handle the form submission:

  1. Add an ID to your form for easier targeting:
    <form id="login-form" method="POST">
      <!-- rest of your form -->
    </form>
    
  2. Add this script to your login.ejs (or a separate JS file):
    document.getElementById('login-form').addEventListener('submit', async (e) => {
      e.preventDefault(); // Stop the form from reloading the page
    
      // Get form data
      const formData = new FormData(e.target);
      const email = formData.get('email');
      const password = formData.get('password');
    
      try {
        const response = await fetch('/api/user/login', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ email, password })
        });
    
        const data = await response.json();
    
        if (data.errors) {
          // Display errors in the alert box
          const alertBox = document.querySelector('.alert');
          alertBox.innerHTML = '';
          Object.values(data.errors).forEach(msg => {
            alertBox.innerHTML += `<p>${msg}</p>`;
          });
          alertBox.classList.remove('d-none'); // Show the alert if it was hidden
        } else {
          // Login successful: redirect to the correct page
          window.location.href = data.redirectUrl;
        }
      } catch (err) {
        console.error('Login failed:', err);
      }
    });
    
  3. Update your signIn controller to return JSON for success too:
    module.exports.signIn = async (req, res) => {
      const { email, password } = req.body;
      try {
        const user = await LoginModel.login(email, password);
        const token = createToken(user._id);
        res.cookie("jwt", token, { httpOnly: true, maxAge });
        
        let redirectUrl = '';
        if (user.role == "seller") {
          redirectUrl = "/success";
        } else if (user.role == "user") {
          redirectUrl = "/success-user";
        } else if (user.role == "superuser") {
          redirectUrl = "/success-admin";
        }
    
        res.status(200).json({ redirectUrl }); // Return redirect path as JSON
      } catch (err) {
        const errors = signInErrors(err);
        res.status(400).json({ errors }); // Keep returning errors as JSON
      }
    };
    

Either approach will work—pick the one that fits your user experience goals!

内容的提问来源于stack exchange,提问作者fr_aken_7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 12:52:29