注册新用户时JWT Payload重复,受保护路由无法获取对应用户信息求助
Hey there, let's break down and fix those two frustrating issues you're running into with your user auth setup. Both problems are tied to how you're generating JWTs and how Passport is validating/retrieving users from them—super common pitfalls for folks new to JWT auth!
1. "JWT Payload is the same every time I register a new user"
Wait, looking at the two JWTs you shared, their payloads are actually different (you can decode them easily to confirm):
- First JWT belongs to
pat1with ID5af43bf3ffcf4cf3bc20e2ac - Second belongs to
pat2with ID5af4408b8006abf4e1de9fb1
That said, if you're seeing duplicate payloads in your own tests, here's the most likely fix:
- Make sure you're generating the JWT from the newly created user object, not static data or an old user reference
- Never include password hashes in your JWT payload—JWTs are base64-encoded (not encrypted), so anyone can read that hash. It's a security risk!
Here's a corrected example of your registration endpoint logic:
// When creating a new user User.create(newUser, (err, createdUser) => { if (err) { return res.status(400).json({ message: 'Failed to create user', error: err }); } // Only include NON-sensitive, necessary user data in the payload const jwtPayload = { id: createdUser._id, username: createdUser.username, email: createdUser.email }; // Sign the token with your secret, set an expiry for security const token = jwt.sign(jwtPayload, process.env.JWT_SECRET, { expiresIn: '24h' }); res.json({ message: 'User created!', token }); });
2. "Protected routes always return the first registered user instead of the one matching the JWT"
This is almost certainly an issue with your Passport JWT strategy's verification callback. The most common mistake here is not querying the database for the user matching the JWT payload's unique identifier (like _id).
Fix your Passport JWT strategy:
Check your config/passport.js file—here's what the correct strategy should look like:
const JwtStrategy = require('passport-jwt').Strategy; const ExtractJwt = require('passport-jwt').ExtractJwt; const User = require('../models/User'); // Adjust path to your User model const opts = {}; // Tell Passport where to find the JWT in the request (usually Authorization header as Bearer token) opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken(); opts.secretOrKey = process.env.JWT_SECRET; // Use your actual secret key passport.use(new JwtStrategy(opts, (jwtPayload, done) => { // Query the database for the user with the ID from the JWT payload User.findById(jwtPayload.id, (err, user) => { if (err) { return done(err, false); // Pass error to Passport } if (user) { // Return only the safe user data (exclude password hash!) const safeUser = { _id: user._id, username: user.username, email: user.email }; return done(null, safeUser); // Pass user to req.user } return done(null, false); // No user found, reject auth }); }));
Common mistakes to check for:
- Did you accidentally use
User.findOne({})without a query condition? That would return the first user in the database every time. - Is your JWT payload storing the correct user ID (e.g.,
idinstead of_id)? Make sure the field name matches what you're using in thefindByIdquery. - Are you using the same
secretOrKeyfor both signing JWTs and verifying them? Mismatched keys will cause Passport to reject tokens, but if you're getting a user back, this is probably not the issue.
Quick Recap
- Always generate JWTs using the freshly created user's data (and omit sensitive fields like password hashes).
- In your Passport JWT strategy, explicitly query the database for the user corresponding to the ID in the JWT payload.
内容的提问来源于stack exchange,提问作者padjo

