I am learning passportjs and i have the following code in my server.js,the problem i am facing is that the passport.use('local',new LocalStrategy({}) in the below code is never called,the rest is working fine except for the localstrategy,been strugling with this for hours!!
I am learning passportjs and i have the following code in my server.js,the problem i am facing is that the passport.use('local',new LocalStrategy({}) in the below code is never called,the rest is working fine except for the localstrategy,been strugling with this for hours!!
const express=require("express");
const bodyParser=require('body-parser');
const ejs=require("ejs");
const cookieParser=require('cookie-parser');
const passport=require('passport');
const LocalStrategy=require('passport-local').Strategy;
const session=require("express-session");
const app=express();
app.set(express.static,'public');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(cookieParser());
app.use(session({secret:'library'}));
app.use(passport.initialize());
app.use(passport.session());
app.post('/auth/signUp',(req,res,next)=>{
console.log('body',req.body)
passport.authenticate('local',(err,user,info)=>{
console.log("whattt",user)
req.login(user,(err)=>{
res.redirect('/auth/profile');
});
})(req, res, next);
});
app.get('/auth/profile',(req,res)=>{
res.json(req.user);
});
app.get("/",async (req,res)=>{
res.render('index.ejs');
});
passport.serializeUser((user,done)=>{
done(null,user.id);
});
passport.deserializeUser((id, done)=> {
console.log("id",id);
let data=[{id:1,name:"malouda"},{id:2,name:"Jason"}];
let user = data.find((obj)=>{ return obj.id === id; });
done(null,user);
});
passport.use('local',new LocalStrategy({
usernameField: 'username',
passwordField: 'password'
},(username,password,done)=>{
user={id:1,name:"malouda"};
console.log("LocalStrategy")
done(null,user);
}));
app.listen(3000,()=>{
console.log("Listening on port 6000");
});
and in my index.js i have the following form
<form name="signUpForm" action="/auth/signUp" method="post" multipart='urlencoded'>
<div class="form-group">
<label for="username">Username</label>
<input type="text" class="form-control" name="username" id="username" placeholder="Username">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" name="password " id="exampleInputPassword1" placeholder="Password">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
Passport LocalStrategy is used for login authentication.
In Signup, you don't need the passport. In Signup, you just create the user by storing it in the database.
You need to add
Passport.authenticate(`local`, (err, user, info) => {}
In your login API to authenticate the user.
As the name suggests, Passport.authenticate authenticates the user credentials. SO first you need to create the user.
Read more here.
Hope I cleared your thoughts.
Related
So I installed body parser via
npm i install express body-parser
and I wrote a simple code designed to input a user into an array after they complete a registration form.
but when I console.log the user it returns undefined for both email and password
here is the server code
const express = require('express');
const path = require('path');
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
const PORT = 3000;
var Users = [{"email":"mike#gmail.com", "password":"456"}];
app.get('/', (req, res) => {
res.render('index.ejs')
})
app.get('/Register.ejs', (req, res) => {
res.render('Register.ejs')
})
app.post('/views/Register.ejs', (req, res) =>
{
const newUser = {
email: req.body.email,
password: req.body.password
};
Users.push(newUser);
res.json(req.body.email);
console.log(Users)
}
)
app.listen(PORT);
here is the html for the register page
<h1>Please Register</h1>
<body>
<form action="/views/Register.ejs" method="POST">
<div class="div">
<label for="email">Enter Email</label>
<input type="email" id="email"for="email" id="email" required>
</div>
<div class="div">
<label for="password">Enter new password</label>
<input type="password" for="password" id="password" required>
</div>
<button type="submit"> Register </button>
</form>
</body>
Only installing body-parser is not enough. You have to put them in the code as middleware.
Top of the code use:
var bodyParser = require('body-parser');
and then use the code in somewhere middle of the code:
app.use(bodyParser.json())
I've built a practice authentication app and it originally worked right when I built it. Now when I try to login or register nothing happens. I can see in my database that it registers a new user but it doesn't move me onto the secret page. When I login with correct credentials and submit it just sits on the login page (but removes the credentials from the form). I've tried to use failureFlash in the login post route but it just errors that it's not a function. I'm not sure what else to do to troubleshoot.
user model:
const mongoose = require("mongoose"),
passportLocalMongoose = require("passport-local-mongoose");
var UserSchema = new mongoose.Schema({
username: String,
password: String
});
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", UserSchema);
app.js:
const express = require("express"),
app = express(),
mongoose = require("mongoose"),
bodyParser = require("body-parser"),
passport = require("passport"),
LocalStrategy = require("passport-local"),
passportLocalMongoose = require("passport-local-mongoose"),
expressSession = require("express-session"),
User = require("./models/user"),
mdbUrl = "This is the url and credentials to my database";
app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({extended:true}));
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
app.use(expressSession({
secret: "some string",
resave: false,
saveUninitialized: false
}));
mongoose.connect(mdbUrl,{useNewUrlParser: true, useCreateIndex: true, useUnifiedTopology: true})
.then(()=> {
console.log("mongooooooose");
})
.catch(err=> {
console.log(err);
})
app.get("/", (req, res)=>{
res.render("home");
});
app.get("/secret", isLoggedIn, (req,res)=>{
res.render("secret");
});
app.get("/register", (req,res)=>{
res.render("register");
});
app.post("/register", (req, res)=>{
req.body.username;
req.body.password;
User.register(new User({username: req.body.username}), req.body.password, (err, user)=>{
if(err){
console.log(err);
res.redirect("register");
}
passport.authenticate("local")(req, res, ()=>{
res.redirect("/secret");
});
});
});
app.get("/login", (req, res)=>{
res.render("login");
});
app.post("/login", passport.authenticate("local",{
successRedirect: "/secret",
failureRedirect: "/login",
}), (req,res)=>{});
app.get("/logout", (req, res)=>{
req.logout();
res.redirect("/");
});
function isLoggedIn(req, res, next){
if(req.isAuthenticated()){
return next();
}
res.redirect("/login");
}
app.listen(3000, ()=>{
console.log("auth started");
});
login.ejs:
<h1>Login</h1>
<form action="/login" method="POST">
<input type="text" placeholder="username" name="username">
<input type="password" placeholder="password" name="password">
<button>Submit</button>
</form>
secret.ejs:
<h1>
Secret Page
</h1>
<p>
this is a test page
</p>
<li>Sign Up!</li>
<li>Sign in</li>
<li>log out</li>
register.ejs:
<h1>register</h1>
<form action="/register" method="POST">
<input type="text" placeholder="username" name="username">
<input type="password" placeholder="password" name="password">
<button>Submit</button>
</form>
<li>Sign Up!</li>
<li>Sign in</li><li>log out</li>
I am using the following stack :
React
PassportJS
NodeJS
Express and express-session
create-react-app with webpack dev server proxying API requests to my node server as mentioned in this article
When I do a form submit, I get an error Cannot POST however when I submit to the SAME url using POSTMAN or curl XPOST, I get results. Here is my server.js code :
'use strict';
const PORT = process.env.PORT || 3001;
const express = require('express');
const app = express();
const path = require('path');
const passport = require('passport')
const initPassport = require('./passport/init');
const session = require('express-session')
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser')
const configDB = require('./config/database.js');
const MongoStore = require('connect-mongo')(session);
var flash = require('connect-flash');
//Connect to mongo
mongoose.connect(configDB.url, {
useMongoClient: true
}).then(() => console.log('connection with database succeeded'))
.catch(err => console.error(err));
// Initialize Passport
initPassport(passport);
// Serve static assets
app.use(express.static(path.resolve(__dirname, '..', 'build')));
//use cookie parser to store data
app.use(cookieParser());
app.use(session({
secret: 'mysecret',
store : new MongoStore ({
db : mongoose.connection.db,
host : '127.0.0.1',
port : '27017',
url : configDB.url
}),
maxAge : 2 * 60 * 60 * 1000,
resave: false,
saveUninitialized: false
})); // session secret
app.use(bodyParser.urlencoded({ extended: false }));
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash()); // use connect-flash for flash messages stored in session
app.post('/signup', passport.authenticate('signup', {
successRedirect: '/',
failureRedirect: '/signup'
}));
app.listen(PORT, () => {
console.log(`App listening on port ${PORT}!`);
});
Form PAGE :
import React, { Component } from 'react';
import constants from 'constants/AuthPageConstants';
class RegisterForm extends Component {
render() {
return (
<div className="tab-pane fade in" id="basic-tab2">
<form action="/signup" method="POST">
<div className="text-center">
<div className="icon-object border-success text-success"><i className="icon-plus3"></i></div>
<h5 className="content-group">{constants.register_form_title} <small className="display-block">{constants.register_form_subtitle}</small></h5>
</div>
<div className="form-group has-feedback has-feedback-left">
<input type="text" name="username" className="form-control" placeholder={constants.register_username_placeholder} />
<div className="form-control-feedback">
<i className="icon-user-check text-muted"></i>
</div>
</div>
<div className="form-group has-feedback has-feedback-left">
<input type="password" name="password" className="form-control" placeholder={constants.register_password_placeholder} />
<div className="form-control-feedback">
<i className="icon-user-lock text-muted"></i>
</div>
</div>
<div className="form-group has-feedback has-feedback-left">
<input type="text" name="email" className="form-control" placeholder={constants.register_email_placeholder} />
<div className="form-control-feedback">
<i className="icon-mention text-muted"></i>
</div>
</div>
<div className="content-divider text-muted form-group"><span>Additions</span></div>
<div className="form-group">
<div className="checkbox">
<label>
<input type="checkbox" className="styled" />
{constants.tos_txt.substring(0, constants.tos_txt.indexOf(" "))} {constants.tos_txt.substr(constants.tos_txt.indexOf(" ") + 1)}
</label>
</div>
</div>
<button type="submit" className="btn bg-indigo-400 btn-block">Register <i className="icon-circle-right2 position-right"></i></button>
</form>
</div>
)
}
}
export default RegisterForm
Signup passport strategy
var LocalStrategy = require('passport-local').Strategy;
var User = require('../models/user');
var bCrypt = require('bcrypt');
module.exports = function(passport){
passport.use('signup', new LocalStrategy({
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) {
console.log("In Signup");
findOrCreateUser = function(){
// find a user in Mongo with provided username
User.findOne({ 'username' : username }, function(err, user) {
// In case of any error, return using the done method
if (err){
console.log('Error in SignUp: '+err);
return done(err);
}
// already exists
if (user) {
console.log('User already exists with username: '+username);
return done(null, false, req.flash('message','User Already Exists'));
} else {
// if there is no user with that email
// create the user
var newUser = new User();
// set the user's local credentials
newUser.username = username;
newUser.password = createHash(password);
newUser.email = req.param('email');
newUser.firstName = "firstName";
newUser.lastName = "lastName";
// save the user
newUser.save(function(err) {
if (err){
console.log('Error in Saving user: '+err);
throw err;
}
console.log('User Registration succesful');
return done(null, newUser);
});
}
});
};
// Delay the execution of findOrCreateUser and execute the method
// in the next tick of the event loop
process.nextTick(findOrCreateUser);
})
);
// Generates hash using bCrypt
var createHash = function(password){
return bCrypt.hashSync(password, bCrypt.genSaltSync(10));
}
}
UPDATE
The issue appears to be due to the presence of the proxy. The form submit works if I directly call the nodejs backend API which is running on a different port (by allowing CORS) and remove the proxy. If I insert the proxy, and make the form point to the weback dev server, then form submit does not call the my nodeJS API. However, proxying works with curl and POSTMAN. Weird how curl works and form submit doesn't. Any pointers here will be helpful.
try to clear browser cache . if you are using chrome
go to settings
type cache in search
browse to bottom and clear cache .
if it doesnt solve the problem please write back
I'm building a website, and i have a registration form where i need to submit a form via POST, and register a user in a mongoDB databse. The website works fine so far, but when i submit the registration form the browser just "waits for localhost" forever. I use EJS as my templating engine, although i don't think that matters.
register.ejs:
<% include partials/header %>
<%include partials/nav %>
<h1>REGISTER</h1>
Login
<form id="registerForm" action="/register" method="post">
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" name="username" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email">
<small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" name="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
<small id="passwordHelp" class="form-text text-muted">Your password must be at least 8 characters long.</small>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<% include partials/footer %>
app.js:
var express = require('express'),
app = express(),
mongoose = require('mongoose'),
passport = require("passport"),
bodyParser = require("body-parser"),
User = require("./models/user"),
LocalStrategy = require("passport-local"),
passportLocalMongoose = require("passport-local-mongoose");
//Set up MongoDB
var mongo = require("mongo");
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var ObjectId = require('mongodb').ObjectID;
var url = 'mongodb://localhost:27017/customerapp';
//MongoJS
var mongojs = require("mongojs");
var db = mongojs("customerapp", ["users"]);
//Mongoose
var mongoose = require('mongoose');
mongoose.Promise = global.Promise
mongoose.createConnection("mongodb://localhost:27017/customerapp");
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({extended: true}));
app.use(require("express-session")({
secret: "wah wah wah",
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
var index = require("./routes/index");
var about = require("./routes/about");
var login = require("./routes/login");
//var register = require("./routes/register");
app.all("index", index);
app.all("about", about);
app.all("login", login);
//app.all("register", register);
// AUTH Routes
//Register get request
app.get("/register", function(req, res) {
res.render("register");
});
//Handle post register req. at '/register'
app.post("/register", function(req, res) {
User.register(new User({
username: req.body.username}),
req.body.password,
function(err, user) {
if(err) {
console.log(err);
return res.render("register");
}
passport.authenticate("local")(req, res, function() {
res.redirect("/secret")
})
});
});
app.listen(process.env.PORT || 3000, process.env.IP, function () {
console.log('Example app listening on port 3000!')
})
You are using three params instead of two, use it like this.
//Handle post register req. at '/register'
app.post("/register", function(req, res) {
User.register(new User({
username: req.body.username,
password: req.body.password
}),
function(err, user) {
if(err) {
console.log(err);
return res.render("register");
}
passport.authenticate("local")(req, res, function() {
res.redirect("/secret")
})
});
});
Check to make sure your versions of mongoDB and mongoose are compatible. You can find a compatibility chart here.
In addition to checking your MongoDB and mongoose versions, you should also check if it's actually connecting to the database by using a callback function when you connect to the server, like so:
//Connecting to database using mongoose.connect with a callback
mongoose.connect("mongodb://localhost:27017/customerapp", function(error) {
if(error) {
console.log("There was an error connecting to MongoDB.");
console.log(error);
} else {
console.log("Successfully connected to MongoDB!");
}
});
This callback may also work with mongoose.createConnection instead of mongoose.connect, but I haven't tried. If neither message prints to the console, then the app is not getting any response from the server, not even an error.
For some reason, as long as mongoDB is running at all, GET requests still seem to work even if the connection attempt hangs, but POST requests run into trouble.
Source: Mongoose never connects to mongodb
I am trying to store some user information in a MongoDB database.
From the front-end (AngularJS) on localhost:9000 I make a POST to the backend (express on localhost:3000)
I'm getting in the header information all the data, including the email-address.
but in the body email is undefined??
Console from Node server:
Console from Web browser:
I must do something wrong with the body parser?
Front-end:
registration View:
<form ng-submit="submit()" name="register" class="form-signin" novalidate>
<h1 class="form-signin-heading text-muted">Register</h1>
<input name="email" ng-model="email" type="email" class="form-control" placeholder="Email address" required autofocus="" required>
<p class="help-block" ng-show="register.email.$dirty && register.email.$invalid">Please enter a proper email.</p>
<input name="password" ng-model="password" type="password" class="form-control" placeholder="Password" required>
<input name="password_confirm" ng-model="password_confirm" type="password" class="form-control" placeholder="Confirm Password" validate-equals='password' required>
<p class="help-block" ng-show="register.password_confirm.$dirty && register.password_confirm.$invalid">please match the password.</p>
<button ng-disabled="register.$invalid" class="btn btn-lg btn-primary btn-block" type="submit">
Submit
</button>
</form>
Front-end controller:
'use strict';
angular.module('app')
.controller('RegisterCtrl', function ($scope, $http, alert) {
$scope.submit = function() {
var url = 'http://localhost:3000/register';
var user = {
email: $scope.email,
password: $scope.password
};
$http.post(url, user)
.success(function(res){
alert('success', 'OK!', 'You are now registered');
})
.error(function(err) {
alert('warning', 'Opps!', 'Could not register');
});
}
});
Back-end NodeJS express server.
var express = require('express');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var app = express();
app.use(bodyParser.json());
//Verbind front-end met backend
app.use(function(req, res, next){
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
next();
})
//MongoDB userModel
var User = mongoose.model('User', {
email: String,
password: String
});
//Reactie op de FRONT END POST voor REGISTRATIE
app.post('/register', function(req, res){
//emailVerification.s end(req.user.email);
//createSendToken(req.user, res);
var user = req.body;
console.log('req.body**' + req.body);
console.log('req.headers**' +req.headers);
var newUser = new User({
email: user.name,
password: user.password
})
newUser.save(function(err) {
//als goed opgeslagen > send status 200 en json new user
res.status(200).json(newUser);
console.log(newUser);
});
});
//MONGODB CONNECTIE =====================================
mongoose.connect('mongodb://....');
//MONGODB CONNECTIE =====================================
var server = app.listen(3000, function(){
console.log('api listening on ', server.address().port);
})
Thanks for your help.
Try using Dot operator , Change your Template as below,(sample code)
<form class="list" name="loginForm" ng-submit="login(credentials)" novalidate>
<label class="item item-input item-floating-label" for="username">
<span class="input-label">UserName</span>
<input type="text" placeholder="Username" id="username" ng-model="credentials.username">
</label>
<label class="item item-input item-floating-label" for="password">
<span class="input-label">Password</span>
<input type="password" placeholder="password" id="password" ng-model="credentials.password">
</label>
<button class="button button-block button-dark activated" type="submit">Logga in</button>
</form>
And in your Controller,
you get username as
var user = $scope.username;
Please read upon this article about Understanding Scopes
https://github.com/angular/angular.js/wiki/Understanding-Scopes#ngRepeat
Happy Coding
I made a typo in "Back-end NodeJS express server"
var newUser = new User({
email: **user.name,**
password: user.password
})
must be:
var newUser = new User({
email: **user.email,**
password: user.password
})