使用Express、Passport、Jwt构建认证API时POST请求遇404错误求助
Hey there! Let's dig into why you're getting that frustrating 404 error when sending POST requests to your auth API. Since you're working directly with SQL instead of a User model, there are a few key areas we need to check first—most 404s here boil down to routing mismatches or middleware order issues.
Common Causes & Fixes
1. Routing Path Mismatch (Most Likely Culprit)
First, double-check that your request URL exactly matches the route you defined:
- If your
routes.jshasrouter.post('/auth/login', ...), and you mounted the router inapp.jswithapp.use('/api', require('./routes')), your full request path should bePOST /api/auth/login—not/auth/loginor/api/login. - Watch out for typos, trailing slashes, or capitalization differences (Express routes are case-sensitive!).
- Confirm you’re using
router.post()(notget) for the login endpoint—mixing these up will definitely throw a 404.
2. Middleware Order is Wrong
Express executes middleware in the order you define them, so misplacing Passport or body-parsing middleware can break your routes:
- Make sure you’re parsing request bodies before mounting Passport or your routes:
// app.js app.use(express.json()); // Parses JSON request bodies app.use(express.urlencoded({ extended: true })); // Parses form-data // Initialize Passport NEXT const passport = require('./passport'); app.use(passport.initialize()); // THEN mount your routes app.use('/api', require('./routes')); - If you accidentally mount routes before Passport or body-parser, your auth handler won’t have access to
req.body(for username/password) or Passport’s authentication methods.
3. Passport Local Strategy Isn’t Properly Registered
Even if your routes are correct, a misconfigured Passport strategy can cause silent failures (though this usually throws a 401, not 404—worth checking anyway):
- In
passport.js, ensure you’ve registered the local strategy correctly, with a valid SQL query to fetch users:const LocalStrategy = require('passport-local').Strategy; const bcrypt = require('bcrypt'); const db = require('./your-mariadb-connection'); // Your DB connection passport.use(new LocalStrategy((username, password, done) => { // Fetch user from MariaDB const query = 'SELECT id, username, password FROM users WHERE username = ?'; db.query(query, [username], (err, results) => { if (err) return done(err); // Handle DB errors if (!results.length) return done(null, false, { message: 'User not found' }); // Verify password hash const isValid = bcrypt.compareSync(password, results[0].password); if (!isValid) return done(null, false, { message: 'Incorrect password' }); // Return user data (without password!) const user = { id: results[0].id, username: results[0].username }; return done(null, user); }); })); - If you forget to call
passport.use()with the LocalStrategy, Passport won’t recognize thelocalauthentication method in your routes.
4. Route Handler Missing Passport Authentication
Make sure your login route is actually using Passport’s authenticate middleware:
// routes.js const jwt = require('jsonwebtoken'); router.post('/auth/login', passport.authenticate('local', { session: false }), (req, res) => { // Generate JWT token once authenticated const token = jwt.sign( { id: req.user.id, username: req.user.username }, process.env.JWT_SECRET, { expiresIn: '1h' } ); res.json({ success: true, token }); });
- Omitting
passport.authenticate('local', ...)here means the route won’t trigger your auth logic, but it shouldn’t throw a 404—unless the route itself is misdefined.
Next Steps to Debug
If none of the above fixes work, share snippets of:
- The middleware/routing section of
app.js - Your full login route in
routes.js - Your Passport strategy configuration in
passport.js
That’ll help pinpoint exactly where the disconnect is!
内容的提问来源于stack exchange,提问作者Vana

