I am trying to create a verification system for my users using nodejs. My code is sending the Auth code yes, then returns the verification sid. But when I use the same sid with the phone number and code given to verify, it throws an error Invalid Parameters. What am I not doing right. Please help. Here is my code
Twilio
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = require("twilio")(accountSid, authToken);
Routes
router.post("/send-otp", (req, res) => {
const { phoneNumber } = req.body;
client.verify.v2.services
.create({ friendlyName: "My Verify Service" })
.then((service) => {
client.verify.v2
.services(service.sid)
.verifications.create({ to: phoneNumber, channel: "sms" })
.then((verification) =>
res.json({ status: verification.status, sid: verification.sid })
)
.catch((error) => res.status(400).json({ error: error.message }));
})
.catch((error) => res.status(400).json({ error: error.message }));
});
// Route to verify OTP
router.post("/verify-otp", (req, res) => {
const { phoneNumber, code, verificationSid } = req.body;
client.verify.v2
.services(verificationSid)
.verificationChecks.create({ to: phoneNumber, code })
.then((verificationCheck) => {
if (verificationCheck.status === "approved") {
res.json({ message: "OTP verification successful." });
} else {
res.status(400).json({ error: "Invalid OTP." });
}
})
.catch((error) => res.status(400).json({ error: error.message }));
});
Related
i'm trying to build a login system with passport and a local strategy. But whenever i try to run the request through axios it does not work, where as with postman the request works.
I get "missing credentials" as error with axios.
here is my axios request :
//api.js
localAuth: (username, password) => {
console.log("running query")
axios({method: "POST", url: "http://localhost:8080/login", data: {username: username, password: password}, withCredentials: true
})
.then(res => {
console.log("Res = ", res);
})
.catch(err => {
if (!err.response) {
// network err
console.log('err: Network err');
} else {
console.log(err.response.data.message);
}
console.log(err);
})
}
Here is my local Strategy :
//passport.js
var options = {
passReqToCallback: false,
usernameField: 'username',
passwordField: 'Password'
};
passport.use(new localStrategy(options, (username, password, done) => {
this.userHelper.isAuthenticated(username, password)
.then(async (response) => {
var user = {username: response.username, id: response.id};
var res = {user: user, token: this.getToken(user), type: type};
var token = await this.tokenHelper.saveToken(res)
return done(null, token)
})
.catch((err) => {
console.log("an error occured : ")
if (err === false) {
return done(null, false, {message: 'Invalid Username or password'})
}
else {
console.log("stratgy error:", err)
return done(err, false);
}
})
}))
and here is my server side request :
//app.js
app.post('/login', (req, res, done) => {
strategy.authenticate('local',{session:true}, (err, user, info) => {
console.log("err = ", err, " user = ", user, " info = ", info)
if (err) {
console.log("error occuring in local authentification strategy")
res.send({sucess: false, message: err})
}
else if (!user) {
console.log("error occuring in local user")
res.send({sucess: false, message: "Unknown user or wrong Password"})
}
else {
console.log("sucess on authorization")
res.send({sucess: true, message: "Authorization suceeded"})
}
})(res, res);
})
The log of the callback variables of strategy.authenticate : err = null user = false info = { message: 'Missing credentials' }
and finally here is the result of postman : {"sucess":false,"message":"Unknown user or wrong Password"}
I've already set usernameField and passwordField, and since i'm using express 6.x.x I don't need to init bodyParser as it's done automatically via express.
Do you guys have any idea on what I'm missing ?
By default axios sends data in JSON format, so you should use one of the official ways described in the official documentation
For instance:
const params = new URLSearchParams();
params.append('username', username);
params.append('password', password);
axios({method: "POST", url: "http://localhost:8080/login", params, withCredentials: true
})
I created Sign up and sign in function in node.js. I am able to sign up user using postman for testing but when I sign in, user, it return error message that I set up. I can't trace what is the problem currently. Can you please help?
export const signin = async (req, res) => {
const { email, password } = req.body;
try {
const oldUser = await UserModal.findOne({ email });
if (!oldUser) return res.status(404).json({ message: "User doesn't exist" });
const isPasswordCorrect = await bcrypt.compare(password, oldUser.password);
if (!isPasswordCorrect) return res.status(400).json({ message: "Invalid credentials" });
const token = jwt.sign({ email: oldUser.email, id: oldUser._id }, secret, { expiresIn: "1h" });
res.status(200).json({ result: oldUser, token });
} catch (err) {
res.status(500).json({ message: "Something went wrong" });
}
};
below is the sign up function...
export const signup = async (req, res) => {
const { email, password, firstName, lastName } = req.body;
try {
const oldUser = await UserModal.findOne({ email });
if (oldUser) return res.status(400).json({ message: "User already exists" });
const hashedPassword = await bcrypt.hash(password, 12);
const result = await UserModal.create({ email, password: hashedPassword, name: `${firstName} ${lastName}` });
const token = jwt.sign( { email: result.email, id: result._id }, secret, { expiresIn: "1h" } );
res.status(201).json({ result, token });
} catch (error) {
res.status(500).json({ message: "Something went wrong" });
console.log(error);
}
};
I have a simple route post route in express, which I created an authentication middleware for.
app.post("/add-recipe", FireBaseAuth, (req, res) => {
if (req.body.body.trim() === "") {
return res.status(400).json({ body: "Recipe cannot be empty" });
}
const newRecipe = {
body: req.body.body,
userHandle: req.user.handle,
createdAt: new Date().toISOString(),
};
db.collection("recipes")
.add(newRecipe)
.then((doc) => {
res.json({ message: `document ${doc.id} created sucessfully` });
})
.catch((err) => {
res.status(500).json({ error: "something went wrong" });
console.error(err);
});
});
When I added my authentication middleware (below) I get the following error
Require stack:
- /Users/persona/.nvm/versions/node/v12.13.1/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js
⚠ Your function was killed because it raised an unhandled error.
Here is the middleware
const FireBaseAuth = (req, res, next) => {
let idToken;
if (
req.headers.authorization &&
req.headers.authorization.startsWith("Bearer ")
) {
idToken = req.headers.authorization.split("Bearer ")[1];
} else {
console.error("No token found");
return res.status(403).json({ error: "Unauthorized" });
}
admin //verify token was issued by the food app and not someone else
.auth()
.verifyIdToken(idToken)
.then((decodedToken) => {
req.user = decodedToken;
console.log(decodedToken);
return db
.collection("users")
.where("userId", "==", req.user.uid)
.limit(1)
.get();
})
.then((data) => {
req.user.handle = data.docs[0].data().handle;
return next(); //allows request to proceed.
})
.catch((err) => {
console.error("Error while verifying token", err);
return res
.status(403)
.json({ Error: "You are not authorized to make this request" });
});
};
I cannot understand as t0 why this is throwing this error.
I am setting access_token in login route but I am getting undefined.
Lines commented below in the code gives undefined why so? How to access the cookie when it is set ? There is another GET route /transactions which gets called on home page after login is success in that route as well I am getting undefined why so? I have also used cookie-parser in server.js file but still not working
transaction GET route https://pastebin.com/DP0NZL5W
const express = require('express');
const router = express.Router();
const jwt = require('jsonwebtoken');
const User = require('../models/userSchema');
router.post('/login', (req, res) => {
const {email, password} = req.body;
console.log("Server Login email: ", email);
console.log("Server Login password: ", password);
User.find({email: email})
.exec()
.then(user => {
console.log("User login user: ", user);
if(user.length < 1){
console.log("user length less")
return res.status(401).json({
message: 'Auth failed'
});
}
bcrypt.compare(password, user[0].password, (err, result) => {
if(err){
return res.status(401).json({
message: 'Auth failed'
});
}
if(result){
const token = jwt.sign({
email: user[0].email,
userId: user[0]._id
}, 'secret', {
expiresIn: "1h"
})
console.log("Cookie token: ", token);
res.cookie('access_token', token, { maxAge: 9000000, httpOnly: true });
// console.log("req.cookies: ", req.cookies)
// console.log("req.cookies['access_token']: ", req.cookies['access_token'])
return res.status(200).json({
message: 'Auth successful',
token: token
})
}
return res.status(401).json({
message: 'Auth failed'
});
})
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
})
})
});
app.use({
credentials: true, // enable cookie receiving
origin: "url of client side" // how can use your api
})
I've been doing some small school project on making our own API and connecting it to an angular front end.
I've been following guide on things and I've came across the problem where my app started throwing internal server error 500 after implementing controllers.
It all worked fine until I've imported the controllers for user registration.
Posts controller works just fine, so does the login part of the ap
I tried logging the errors but it wouldnt output anything.
Here is my code:
user route
const express = require("express");
const UserController = require("../controllers/user");
const router = express.Router();
router.post("/signup", UserController.createUser);
router.post("/login", UserController.userLogin);
module.exports = router;
User controller
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
const User = require("../models/user");
exports.createUser = (req, res, next) => {
bcrypt.hash(req.body.password, 10).then(hash => {
const user = new User({
email: req.body.email,
password: hash
});
user
.save()
.then(result => {
res.status(201).json({
message: "User created!",
result: result
});
})
.catch(err => {
res.status(500).json({
message: "Invalid authentication credentials!"
});
});
});
}
exports.userLogin = (req, res, next) => {
let fetchedUser;
User.findOne({ email: req.body.email })
.then(user => {
if (!user) {
return res.status(401).json({
message: "Auth failed"
});
}
fetchedUser = user;
return bcrypt.compare(req.body.password, user.password);
})
.then(result => {
if (!result) {
return res.status(401).json({
message: "Auth failed"
});
}
const token = jwt.sign(
{ email: fetchedUser.email, userId: fetchedUser._id },
"b9SNz3xg9gjY",
{ expiresIn: "1h" }
);
res.status(200).json({
token: token,
expiresIn: 3600,
userId: fetchedUser._id
});
})
.catch(err => {
return res.status(401).json({
message: "Invalid authentication credentials!"
});
});
}
I am expecting to be able to register an account which will be able to post new posts. It all worked just fine until I've made controllers and moved the requests and functions into controller file.
I really apologize for asking this probably simple question, but my programming skills are still low
In userLogin, when the user doesn't exist, you return res.status(401)..., which is chained to the next .then call as result (instead of your expectation that it would be the value returned by bcrypt.compare).
What you can do is instead of:
if (!user) {
return res.status(401).json({
message: "Auth failed"
});
}
try
if (!user) {
throw new Error("Auth failed");
}
which will be caught in your .catch.