'login with email or phone or username in node js
How can I login email or phone or username with password in node js and mongodb? user can login with email and password, username and password, phone and password. this is like Instagram login module. here is my script:
const login = catchAsync(async (req, res) => {
const { email, password } = req.body;
const user = await User.findOne({ email });
if (!user || !(await user.isPasswordMatch(password))) {
throw new ApiError(httpStatus.UNAUTHORIZED, 'Incorrect email or password');
}
const tokens = await tokenService.generateAuthTokens(user.id);
const response = { user: user.transform(), tokens };
res.send(response);
});
Solution 1:[1]
What you can try is that don't restrict your code to accept the email only make it general and find the user based on the input like this
const login = catchAsync(async(req, res) => {
const {
userEmailPhone,
password
} = req.body;
//suppose in your DB you have email, phone and username fields
const user = await User.findOne({
$or: [{
"email": userEmailPhone
}, {
"phone": userEmailPhone
}, {
"userName": userEmailPhone
}]
});
if (!user || !(await user.isPasswordMatch(password))) {
throw new ApiError(httpStatus.UNAUTHORIZED, 'Incorrect email or password');
}
const tokens = await tokenService.generateAuthTokens(user.id);
const response = {
user: user.transform(),
tokens
};
res.send(response);
});
NOTE: Make sure Email, Phone and Username is unique for every user
Hope this helps
Solution 2:[2]
I needed same then I created this simple functionality to allow login with username and password, email and password or phone and password. There should be a better way or algorithm, but I couldn't find it. I hope it meets your need.
// authRoutes.js//
// Login route
router.post("/login", loginController);
// authController.js
// Login Controller
export const loginController = async (req, res) => {
if (req.body.userDetail == "" || req.body.password == "")
res.status(400).json("All Fields Are Required!");
try {
let user;
try {
user = await User.findOne({ username: req.body.userDetail });
if (!user) user = await User.findOne({ email: req.body.userDetail });
if (!user) user = await User.findOne({ phone: req.body.userDetail });
const validatedUser = await bcrypt.compare(
req.body.password,
user.password
);
!validatedUser && res.status(403).json("Wrong credentials!");
const { password, ...others } = user._doc;
res.status(200).json(others);
} catch (error) {
res.status(404).json("User Not Found!");
}
} catch (error) {
res.status(500).json("Something Else Went Wrong!");
}
};
Solution 3:[3]
First, you need to check if the email and password exist and then you need check if email and password combination is true. in your case, You can also add a field like a mobile with an email.
const login = catchAsync(async (Request, Response, next) => {
const { email, password } = Request.body;
//check if email and password exists
if (!email || !password) {
throw new ApiError(httpStatus.UNAUTHORIZED, 'Please provide email and password');
}
//check if user exist and password correct
const user = await User.findOne({ email }).select('+password');
if (!user || !(await user.isPasswordMatch(password, user.password))) {
throw new ApiError(httpStatus.UNAUTHORIZED, 'Incorrect email or password');
}
//if everything ok, send token to the client
const tokens = await tokenService.generateAuthTokens(user.id);
const response = { user: user.transform(), tokens };
res.send(response);
});
P.S: It is not good practice to throw an error directly. Use a different approach.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Hadi Mir |
Solution 2 | ennas-de |
Solution 3 |