dmikester1
dmikester1

Reputation: 1362

PassportJS - Getting back custom error message from Node server to client

I've looked at several similar questions on here and none seem answer my specific question. But I am just trying to pass back a custom message on login error and can't figure out how to get it.

So here is my local strategy code in my passport.js file:

passport.use(
    new LocalStrategy((username, password, done) => {
        User.userSearch(username)
            .then((user) => {
                console.log({ user });
                if (!user.allow_login) {
                    // don't allow login, send back message
                    return done(null, false, {
                        message: 'Login disabled right now.',
                    });
                } else if (user?.password) {
                ...

And then the login route in my user gateway:

router.post(
    '/login',
    (req, res, next) => {
        if (req.isAuthenticated()) {
            req.session.touch();
        }
        next();
    },
    passport.authenticate('local', {
        failureRedirect: '/login',
        failureFlash: true,
    }),
    (req, res) => {
        console.log({ res });
        console.log({ req });
        // if you made it here, the user is real and authentic
        // check rememberMe and set cookie age accordingly
        if (req.body.rememberMe) {
            req.session.cookie.maxAge = 30 * 24 * 60 * 60 * 1000; // Cookie expires after 30 days
        } else {
            req.session.cookie.expires = false; // Cookie expires at end of session
        }
        // create new user object with email, customer name, and type

        const user = {
            email: req.user.email,
            type: req.user.type,
            first: req.user.first_name,
            last: req.user.last_name,
            filled_in: req.user.filled_in_basic_profile,
        };
        res.status(200).json({ user });
    }
);

Every other example I can find seems to use different code after the passport.authenticate("local" part. All I'm getting back in the client is a 401.

**Update: ** Adding client code where the login function is called if that helps.

export const login = (user) => {
    return (
        axios
            // .post('/users/login', {
            .post(baseURL + '/users/login', {
                //.post(baseURL + '/auth/', {
                username: user.email,
                password: user.password,
                rememberMe: user.rememberMe
            })
            .then((res) => {
            ...

Upvotes: 5

Views: 910

Answers (2)

Bhaskar
Bhaskar

Reputation: 346

You can use express-flash for showing error messages to client.

const flash = require('express-flash);
const session = require('express-session')
app.use(session({
  secret: 'hidden',
  cookie: {
      maxAge: 60000
 }
}))
app.use(flash());

so now configuring flash as middleware you will have access to req.flash() function . You can now set custom flash messages.

//route for passport strategy
router.post("/login", passport.authenticate("local", {
    failureRedirect: "/login",
    failureFlash: true,
}));
     
// render error to client
router.get("/error", function(req, res, next) {
return res.render("error", {
    error: req.flash("error"),
});
});
                                                                                      

On client side you will have access to error object. If you are using ejs then you can do if like this

<% if(typeof(error) != "undefined"){ %>
    <%= error %> 
<% } %>

You also have access to locals.error like so

<%= locals.error %>

In react you have to make an axios post request. On the server side you can send response as an object. Login route will be like this

router.get('/login', passport.authenticate(//some code), (req, res) => {
    const error = req.flash('error') // check for empty variables
    res.json(error)// 
}) 

Upvotes: 1

Ionică Bizău
Ionică Bizău

Reputation: 113385

The code is expected to work I assume. However, I suggest debugging this part:

user.allow_login

Check if user.allow_login is actually false before the if.

Upvotes: -1

Related Questions