I am using passport with local strategy .but I want to send message and status when credential is not match or (user is not exit is DB)
here is code
router.js
const passport = require('passport');
const passportConfig = require('../passport')
const passportSignIn = passport.authenticate('local', { session: false });
router.route('/login',)
.post(passportSignIn,controller.login)
on controller file
login: async (req, res, next) => {
console.log(req.body);
res.json({status:200})
}
passport.js
passport.use(new LocalStrategy({
usernameField: 'email'
}, async (email, password, done) => {
const user = await db.User.findOne({where: {email: email}});
if (!user) {
return done(null, false,{message:"No user exit"});
}
const isMatch = await bcrypt.compare(password, user.dataValues.password);
console.log(isMatch, 'isMatch');
if (!isMatch) {
return done(null, false);
}
// Otherwise, return the user
done(null, user);
}))
Client code
when user click on login button it goes to /login path first it goes to passportSignIn function or below function.
`new LocalStrategy({
usernameField: 'email'
}, async (email, password, done) => {`
now if user not found I want to send this message on the client as the response ("No user exit")
return done(null, false,{message:"No user exit"});
You have to update your login controller, like so:
login: (req, res, next) => {
console.log(req.body);
passport.authenticate('yourStrategy', function(err, user, info) {
if (err) {
return res.status(500).json("Internal Server Error");
}
if (!user) {
// This 'info' variable below would be - { message: "No user exit" }
// as you passed in the done() callback as the third param
return res.status(404).json(info.message);
}
}
}
Related
hello i new in backend and want to make a Authenticate facebook api with node js using express and i use passport but its not work and give me a page of html code as a response to sign in with facebook account this can handle when use web page the api may use with mobile application
my passport file that i use
const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcryptjs');
const passport = require('passport')
const FacebookStrategy = require('passport-facebook').Strategy;
// Load User model
const User = require('../Schema/user');
// ---------------- Local Auth -------------- //
passport.use(
new LocalStrategy({ usernameField: 'email' },
(email, password, done) => {
// Search For Match user
User.findOne({ email: email }).then(user => {
if (!user) {
console.log("That email is not registered")
return done(null, false, { message: 'That email is not registered' });
}
// Compare the Two Password password
bcrypt.compare(password, user.password, (err, isMatch) => {
// if (err) throw err;
if (err) {
console.log(err)
return done(err);
}
if (isMatch) {
console.log("matching email");
return done(null, user);
} else {
console.log("Password incorrect");
return done(null, false, { message: 'Password incorrect' });
}
});
});
})
);
//------------------ Facebook Auth ---------------//
passport.use(new FacebookStrategy({
clientID: process.env.FACEBOOK_APP_ID,
clientSecret: process.env.FACEBOOK_APP_SECRET,
ccallbackURL: "/auth/facebook/callback",
profileFields: ['id', 'emails', 'name'],
},
async (accessToken, refreshToken, profile, done) => {
try {
const userData = {
firstName: profile._json.first_name.toLowerCase(),
lastName: profile._json.last_name.toLowerCase(),
email: profile._json.email,
isConfirmed: true,
};
// const user = await userService.registerWithThirdParty(userData);
done(null, user);
} catch (error) {
console.error(error.message);
done(null, false);
}
}
));
passport.serializeUser(function (user, done) {
done(null, user.id);
});
passport.deserializeUser(function (id, done) {
User.findById(id, function (err, user) {
done(err, user);
});
});
module.exports = passport;
my index.js file
router.get("/auth/facebook", passport.authenticate("facebook"));
router.get("/auth/facebook/callback",
function (req, res, next) {
passport.authenticate('facebook', function (err, user, info) {
if (err) { return next(err); }
if (!user) { return res.json({ message: info.message }) }
req.logIn(user, function (err) {
if (err) { return next(err); }
return res.json({ msg: "succes Login", user: user });
});
})(req, res, next);
}
);
when i use local signup or login it work but when i use facebook login dont work and give me a full html to sign in and i cant handled it in my api.
hint : i use passport-facebook
you can use this script to make authentication to facebook + passport js:
user.controller.js
import passport from "passport";
import dotenv from "dotenv";
import strategy from "passport-facebook";
import userModel from "../user/user.model";
const FacebookStrategy = strategy.Strategy;
dotenv.config();
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(obj, done) {
done(null, obj);
});
passport.use(
new FacebookStrategy(
{
clientID: process.env.FACEBOOK_CLIENT_ID,
clientSecret: process.env.FACEBOOK_CLIENT_SECRET,
callbackURL: process.env.FACEBOOK_CALLBACK_URL,
profileFields: ["email", "name"]
},
function(accessToken, refreshToken, profile, done) {
const { email, first_name, last_name } = profile._json;
const userData = {
email,
firstName: first_name,
lastName: last_name
};
new userModel(userData).save();
done(null, profile);
}
)
);
user.router.js
import express from "express";
import passport from "passport";
import userController from "./user.controller";
const userRouter = express.Router();
userRouter.get("/auth/facebook", passport.authenticate("facebook"));
userRouter.get(
"/auth/facebook/callback",
passport.authenticate("facebook", {
successRedirect: "/", // to add check you can use this value successRedirect also the next value failureRedirect
failureRedirect: "/fail"
})
);
userRouter.get("/fail", (req, res) => {
res.send("Failed attempt");
});
userRouter.get("/", (req, res) => {
res.send("Success");
});
export default userRouter;
index.js
import express from "express";
import { json } from "body-parser";
import passport from "passport";
import { connect } from "./utils/db";
import userRouter from "./user/user.routes";
const app = express();
const port = 3000;
app.use(passport.initialize());
app.use(json());
app.use("/", userRouter);
app.listen(port, async () => {
await connect();
console.log(`Server listening on ${port}`);
});
I have configured passportJS with node express app but when I make login/register request then in that case req.user is undefined any idea what is wrong am I missing something in configuring passport js? I have used express-session and mongoDB store for storing sessions
passport-config.js:
const passport = require("passport");
const LocalStrategy = require("passport-local").Strategy;
const User = require("./Models/userSchema");
passport.use(
new LocalStrategy(
{
usernameField: "email",
passwordField: "password",
},
async (email, password, done) => {
try {
const user = await User.findOne({ email });
// Username/email does NOT exist
console.log("user in config", user);
if (!user) {
return done(null, false, {
message: "Username/email not registered",
});
}
// Email exist and now we need to verify the password
const isMatch = await user.isValidPassword(password);
return isMatch
? done(null, user)
: done(null, false, { message: "Incorrect password bro" });
} catch (error) {
done(error);
}
}
)
);
passport.serializeUser(function (user, done) {
done(null, user.id);
});
passport.deserializeUser(async function (id, done) {
const user = await User.findById(id);
done(null, user);
});
server.js file: https://pastebin.com/NfpvXSFf (see line 39)
I would try:
async (req, res) => {
{email, password, done} = req.body;
(you need a body-parser for that)
passport.js
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var user = require('../modal/admin');
exports.passport = (passport) => {
passport.use(new LocalStrategy({
usernameField: 'username',
passwordField: 'password'
},
(username, password, done, req) => {
console.log(req)
user.findOne(({ username: username }), async (err, user) => {
if (err) { return done(err); }
if (!user) { return done(null, false); }
const cpassword = await bcrypt.compare(password, user.password);
if (!cpassword) { return done(null, false); }
const token = jwt.sign(
{
id:user.id,
username:user.username
},
"shubham"
);
adminRecords = {
token:token
}
req.data = adminRecords ====>>>> Error here
console.log(adminRecords)
return done(null, user, adminRecords);
});
}
))
};
passport.serializeUser(function (user, done) {
done(null, user)
})
passport.deserializeUser(function (id, done) {
user.find(id, function (err, user) {
done(err, user)
});
});
route.js
router.post('/login', passport.authenticate('local'));
It's giving error req.data is not defined. I am using passport local strategy and want to return jwt token in req.data. It is not taking req parameter correctly.
Callback function have only 3 params
passport.use(new LocalStrategy({
usernameField: 'username',
passwordField: 'password'
},
(username, password, done, req) => { // callback function have only 3 params
// Additional codes
Solution try to use middleware when you authenticate
app.use(request, response, next) => { passport.authenticate('local', (err, token, info) => {
if (token) {
request.login(token, () => { // Do your logic });
} else { }
})(request, response, next); });
I am making an android app in partnership with a colleague, he is an Android developer and I know very little about android dev. I do the backend stuff, I made the login and auth using node.js, express, and passport.js.
I hosted the server locally and used postman to check the auth and registration processes, all were working fine. I am getting the status codes my friend wanted for his Front-end. In the authentication part using passport.js when success I am passing req.user which should return the user body, so that my friend on the Front-end can use the field user.firstName from user object to display a welcome message.
Through Postman, the user body is getting defined and I am getting a user object with all fields in the Postman window, but through the app it is giving an error.
firstName is undefined property.
Passport.js logic:
const LocalStrategy = require('passport-local').Strategy;
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
//load user model
const User = require('../models/UserSchema');
module.exports = function(passport){
passport.use(
new LocalStrategy({usernameField: 'roll'}, (roll, password, done) => {
//find user
User.findOne({roll: roll})
.then(user =>{
if(!user){
return done(null, false, {message: 'Roll number not registered'});
}
//match password
bcrypt.compare(password, user.password, (err, isMatch) =>{
if(err) throw err;
if(isMatch){
return done(null, user);
}else{
return done(null, false, {message: 'Password incorrect'});
}
})
})
.catch(err => console.log(err));
})
);
/*passport.serializeUser( function(id, done) {
done(null, User.roll);
});
passport.deserializeUser(function(id, done){
User.findById(roll, function(err, user){
done(err, user);
});
});*/
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser((_id, done) => {
User.findById( _id, (err, user) => {
if(err){
done(null, false, {error:err});
} else {
done(null, user);
}
});
});
}
Login Route:
//Login Handle
router.post('/login', (req, res, next) =>{
console.log('/user/login')
passport.authenticate('local', {
successRedirect: '/success',
failureRedirect: '/failure',
session: true,
failureFlash: false
})(req, res, next);
//res.json(pass.user.name);
});
/success route:
router.get('/success', (req, res) => {
console.log(req);
let message = 'Login Succesful';
//let user = req.user.firstName
res.status(200).json({'message':message, 'user': req.user.firstName});
})
I guess you are also using body-parser or express.json() to parse the incoming body request to JSON. If this is the case you should send the response back like this:
req.body.user.firstName
For POST requests: req.body
For GET parameters: req.params
For GET query strings: req.query
I've a use-case. My application has multiple users where not all users have the access to all the functionalities in the application. I have to restrict them from accessing the application. For that, I've been writing logic that works as the gateway.
I've created different rules which provides a different kind of authentication methods.
When a user log in to the application, will generate a JWT token upon successful login. That token will be authenticated using the rules given.
Here's my code.
server.js
global.app = new require("express")();
global.passport = require("passport");
require("./bin/kernal");
require('./bin/passport');
----Remaining Code----
TokenAuth.js
var passport = require("passport");
require("../../bin/passport");
module.exports= function (req, res, next) {
passport.authenticate('jwt', function (error, user) {
console.log(user);
if (error) return next(error);
if (!user) return res.status(401).json({"error":"Incorrect data", "status":401, "success":false});
//req.user = user;
next();
})(req, res, next);
};
module.exports.UserAuth = function(req, res, next){ // Error Web Response
passport.authenticate('user_rule', function (error, user) {
if (error) return next(error);
if (!user) return res.status(500).json({"message":"No User found", "status":500, "success":false});
//req.user = user;
next();
})(req, res, next);
};
Passport.js
var passport = require("passport");
app.use(passport.initialize());
app.use(passport.session());
require('../app/middlewares/TokenAuth')
passport.serializeUser(function (user, done) {
done(null, user.id);
});
passport.deserializeUser(function (id, done) {
User.findOne({_id: id}, function (err, user) {
done(err, user);
});
});
var JwtStrategy = require('passport-jwt').Strategy;
var ExtractJwt = require('passport-jwt').ExtractJwt;
var options = {};
options.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
options.secretOrKey = process.env.jwt_secret;
passport.use(new JwtStrategy(options, function (payload, done) {
console.log(payload)
User.findOne({_id: payload._id}, function (error, user) {
if (error) return done(error, false);
if (!user) return done(null, false);
// req.auth_user = {"_id":user._id,"email":user.email,"name":user.name,"status":user.status}
done(null, user);
});
}));
passport.use('user_rule', // UserAuth in TokenAuth.js has to use this functionality
new JwtStrategy(options,async function (payload, done) {
console.log(payload)
let err, authUser,companyResource;
[err,authUser] = await to(CompanyContacts.findById(payload._id).populate('company',
["accountid","company_name","email","status"]).lean().exec());
if (err) return done(err, false);
if (!authUser) return done(null, false);
let user= authUser;
if(user.status==true && user.company.status==true){
req.auth_user = {"_id":user._id,"email":user.email,"name":user.fullname,status:user.status,isPrimary:user.primarycontact};
req.auth_company=user.company._id;
req.isAdmin=false;
req.auth_role=user.role;
done(null, user);
}else{
return done(err, false);
}
})
);
user_api.js
router.get("/all/menus",TokenAuth,MenuController.getAllDropDowns);
router.post("/company/user/signin", TokenAuth.UserAuth, AuthController.customerlogin);
Here, when the post api get executed, only the user who gets authenticated has to get the access that api.
But the problem here is, whenever I use this authentication methods, I'm getting the error specified below.
{
"error": "Incorrect data",
"status": 401,
"success": false
}
As per my knowledge, the data is not going into the Passport.js file to get authenticate.
Is this approach good, or do I need to make any changes in this code to make it work?