How to exclude password from user object sent in response in express.js?

Viewed 38

I am returning a response object with the user and jwt token whenever a user logs in. But I want to exclude the password field when the user is sent in the response.

Controller:

const loginUser = asyncHandler(async (req, res) => {
  const { email, password } = req.body;

  // Check for user email
  const user = await User.findOne({ email });

  if (user && (await bcrypt.compare(password, user.password))) {
    res.json({
      user: user,
      token: generateToken(user._id),
    });
  } else {
    res.status(400);
    throw new Error("Invalid credentials");
  }
});

if I exclude the password when finding the user like this:

const user = await User.findById(decoded.id).select("-password");

Then bcrypt's compare method will not work as it needs user.password.

Please tell me how I can exclude password from user object in JSON response?

1 Answers

You can set undefined to the user before returning the user.

const loginUser = asyncHandler(async (req, res) => {
  const { email, password } = req.body;

  // Check for user email
  const user = await User.findOne({ email });

  if (user && (await bcrypt.compare(password, user.password))) {
    user.password = undefined;
    res.json({
      user: user,
      token: generateToken(user._id),
    });
  } else {
    res.status(400);
    throw new Error('Invalid credentials');
  }
});

Or you can use the toJSON method in the user schema to exclude password:

const userSchema = new mongoose.Schema(
  {
    email: {
      type: String,
      required: true,
      unique: true,
    },
    password: {
      type: String,
      required: true,
    },
  },
  {
    toJSON: {
      transform(doc, ret) {
        delete ret.password;
      },
    },
  },
);
Related