Redux+React环境下Express忽略403错误:重置密码异常排查
Let's break down what's going wrong here and fix it step by step:
1. Frontend Validation Isn't Catching Empty Passwords
In your updatePassword method, the check if(password != null) doesn't block empty strings—since an empty string isn't null, it will still call updatePass(creds) even if the user submits a blank password.
Fix this by validating that the password is a non-empty, non-whitespace string:
updatePassword = e => { e.preventDefault(); const { username, password } = this.state; const creds = { username, password }; // Check for valid password input if (password && password.trim().length > 0) { this.props.updatePass(creds); } else { console.log('Please enter a valid password'); // Optional: Set local state error to show a user-facing message this.setState({ error: true }); } };
2. Backend Doesn't Validate Password Input
Even if frontend validation fails, a user could bypass it (e.g., via dev tools). Your backend currently accepts empty passwords, hashes them, and returns a success status. Add a check for a valid password before proceeding:
router.put('/updatePassword', (req, res, next) => { passport.authenticate('jwt', { session: false }, (err, user, info) => { if (err) { console.log(err); } if (info != undefined) { console.log(info.message); res.status(403).send(info.message); } else { // Add password validation here if (!req.body.password || req.body.password.trim() === '') { return res.status(400).send('Password cannot be empty'); } models.User.findOne({ where: { username: req.body.username, }, }) .then(user => { // ... rest of your existing code ... }); } })(req, res, next); });
3. Backend Promise Chain Doesn't Wait for Password Update
You're not returning the user.update() promise in your chain, so the success response is sent before the password is actually saved to the database. This creates a race condition that could lead to inconsistent state. Fix it by returning the update promise:
bcrypt .hash(req.body.password, BCRYPT_SALT_ROUNDS) .then(hashedPassword => { // Return the update promise to ensure the next `then` waits for it to complete return user.update({ password: hashedPassword }); }) .then(() => { console.log('password updated'); res.status(200).send({ auth: true, message: 'password updated' }); });
4. Redux Error Handling Will Now Trigger Correctly
Once the backend returns proper error status codes (like 400 for empty passwords), your Redux action's catch block will run, dispatching UPDATEPASS_FAIL. This sets state.account.error to true, which will trigger your error component to render as expected.
With these fixes:
- Empty passwords are caught both in the frontend and backend
- The backend ensures the password is saved before sending a success response
- Redux correctly handles errors and updates the state to show your error message
内容的提问来源于stack exchange,提问作者randal

