Open AdrieneTZ opened 1 year ago
related question on stackoverflow
This should work after I check the stackoverflow issue & official doc:
In case of authentication failure, the verify callback supplies a message, via the message option, describing why authentication failed. This will be displayed to the user when they are re-prompted to sign in, informing them of what went wrong.
back-end/config/passport.js
-if (!user) return callbackFn(null, false)
+if (!user) return callbackFn(null, false, { message: 'User not found.' })
...
-isValidPassword ? callbackFn(null, user) : callbackFn(null, false)
+isValidPassword ? callbackFn(null, user) : callbackFn(null, false, { message: 'Password is wrong. '})
By passing a third arg: { message: 'YOUR_ERROR_MESSAGE' }
to callbackFn
, we can catch it like this:
back-end/routes/modules/user.js
router.post(
'/logIn',
-passport.authenticate('local', { session: false }),
-userController.logIn
+(req, res, next) => {
+ passport.authenticate('local', { session: false }, (err, user, info) => {
+ if (!user) return res.status(401).json(info)
+ // Sign a token
+ const token = jwt.sign(user, process.env.JWT_SECRET, { expiresIn: '7d' })
+ return res.status(200).json({ token })
+ })(req, res, next)
+}
)
Simply remove the userController.logIn
and replace the second arg passport.authenticate('local', { session: false })
with an anonymous arrow function:
(req, res, next) => {
passport.authenticate('local', { session: false }, (err, user, info) => {
// (err, user, info) here is corresponding to the
// callbackFn(null, user) or callbackFn(null, false, { message: "wrrrrr" })
// Below will reply error message like "User not found." or "Password is wrong."
// Depends on your local strategy in "passport.js"
if (!user) return res.status(401).json(info)
// Sign a token
const token = jwt.sign(user, process.env.JWT_SECRET, { expiresIn: '7d' })
return res.status(200).json({ token })
})(req, res, next)
}
Now the practice of authenticating errors is in
user-controller.logIn
. I want to move those processes topassport.js
because going into the user-controller without passing authentication is so weird. Also, it's not logical that let the controller check the possible errors. The only workuser-controller/logIn
should do is ask JWT to sign a token and return this token.In
./config/passport.js
, there is no argument calledres
that does the early return process when any possible error happens, and it's unable to customize error conditions in passport-local strategy. I'm still figuring out how to add an early return process and meanwhile not necessarily create too many middlewares (functions).