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
})
Related
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 }));
});
I have created a middleware that authenticate the user that whether he is verified or not. At the first request when i try to go on protected routes it gives me success messages and verifies the jwt token but when i hit the same request again i get this error.
here is my code !
const Anime = require("../models/admin_model");
const jwt = require("jsonwebtoken");
const checkUserAuthentication = async (req, res, next) => {
const token = req.headers.token;
if (token) {
jwt.verify(token.toString(), "secret", async (err, token_decode) => {
if (err) {
return res.json({
status: 0,
err: err,
msg: "Authorization failed",
});
}
console.log(token_decode);
res.json({ data: token_decode });
next();
return;
});
}
return res.json({
status: 0,
msg: "Authorization failed",
});
};
module.exports = checkUserAuthentication;
res.json({ data: token_decode });
next();
You are responding with JSON, then you are handing control over to the next middleware or route endpoint which (presumably) is making its own response (but it can't because you already responded).
I changed my code to this.
Well maintained if-else statements.
const Anime = require("../models/admin_model");
const jwt = require("jsonwebtoken");
const checkUserAuthentication = async (req, res, next) => {
const token = req.headers.token;
if (token) {
jwt.verify(token.toString(), "thisissecs", async (err, token_decode) => {
if (!err) {
console.log(token_decode);
res.json({ data: token_decode });
next();
} else {
return res.json({
status: 0,
msg: "Authorization failed",
});
}
});
}
else{
return res.json({
status: 0,
msg: "Authorization failed",
});
}
};
module.exports = checkUserAuthentication;
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'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.
I am using nodejs and sequelize to create simple user registration, I already did the login and register, but when login is a success I don't get any token.
I have tried to console.log the token to see if I get some result, but there is no response in the console related to the token.
Here is my code:
var express = require('express');
var User = require('../../models').User;
var router = express.Router();
var jwt = require('jsonwebtoken');
var app = require('../../app');
/*var token = jwt.sign(user, app.get('superSecret'), {
expiresInMinutes: 1440 // expires in 24 hours
});*/
router.post('/', function (req, res, next) {
if (JSON.stringify(req.body) == "{}") {
return res.status(400).json({ Error: "Login request body is empty" });
}
if (!req.body.username || !req.body.password) {
return res.status(400).json({ Error: "Missing fields for login" });
}
// search a user to login
User.findOne({ where: { username: req.body.username} }) // searching a user with the same username and password sended in req.body
.then(function (user) {
if (user && user.validPassword(req.body.password)) {
//return res.status(200).json({ message: "loged in!" }); // username and password match
// create a token
var token = jwt.sign(user, app.get('superSecret'), {
expiresInMinutes: 1440 // expires in 24 hours
});
// return the information including token as JSON
res.json({
success: true,
message: 'Enjoy your token!',
token: token
});
}
else{
return res.status(401).json({ message: "Unauthorized" }); // if there is no user with specific fields send
}
}).catch(function (err) {
return res.status(500).json({ message: "server issues when trying to login!" }); // server problems
});
});
module.exports = router;
You should use express-jwt library. https://www.npmjs.com/package/express-jwt
It's middleware for express. Example:
var jwt = require('express-jwt');
app.get('/protected',
jwt({secret: 'shhhhhhared-secret',
credentialsRequired: false,
getToken: (req) => req.cookies.id_token // when cookies are using. 'id_token' is cookie's name
}),
function(req, res) {
if (!req.user.admin) return res.sendStatus(401);
res.sendStatus(200);
});
Also you may write as app.use(...) or app.anyRequest(...)