I'm trying to let the user login using the username or email, I didn't know how to implement it, now I have the user logging in using it's email.
auth.js
:
//LOGIN
router.post("/login", async (req, res) => {
try {
const user = await User.findOne({ email: req.body.email });
!user && res.status(400).json("Wrong credentials!");
const validated = await bcrypt.compare(req.body.password, user.password);
!validated && res.status(400).json("Wrong credentials!");
const { password, ...others } = user._doc;
return res.status(200).json(others);
} catch (err) {
return res.status(500).json(err);
}
});
How can I let the user login using email or username with one input?
CodePudding user response:
You can identify whether it is email or userame.
const isEmail=/^(([^<>()[\]\\.,;:\s@"] (\.[^<>()[\]\\.,;:\s@"] )*)|(". "))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9] \.) [a-zA-Z]{2,}))$/.test(req.body.identifier)
Then you can use query accordingly.
const user = await User.findOne(
isEmail ? ({ email: req.body.identifier }) : ({username: req.body.identifier})
);
This will make your query simpler and faster.
CodePudding user response:
You can try to get a user from both email and username. If its from the same input and you can't make the difference from your client app you can do something like that.
const user =
(await User.findOne({ email: req.body.loginInput })) ||
(await User.findOne({ username: req.body.loginInput }))
But that would do 2 db queries for each user that want to sign in with username.
The best would be to use a reggex on your client app that recognize if its an email and then you could have 2 differents fields on you POST
data.
CodePudding user response:
It seems you're using Sequelize to query your database.
You can use the where
clause and provide an Op.or
to filter by email
or username
.
const { Op } = require("sequelize");
// Query
const user = await User.findOne({
where: {
[Op.or]: [
{
email: {
[Op.like]: req.body.email,
},
},
{
username: {
[Op.like]: req.body.username,
},
},
],
},
})