Passport Local strategy not called - javascript

I use angularJS+passport to perform user authentication and hence, i set up these below.
HTML:
<div ng-controller="logincontroller">
<form>
Email:<input type="text" ng-model="user.email"/>
Password:<input type="password" ng-model="user.password"/>
<div ng-click=loginUser()>Submit</div>
</form>
</div>
In client side javascript:
app.controller('logincontroller',function($scope,$http){
$scope.loginUser=function(){
$http.post('/loginUser',JSON.stringify($scope.user));
}
})
ON app.js
var bodyParser = require('body-parser');
var cookieParser=require('cookie-parser');
var passport=require('passport');
var LocalStrategy=require('passport-local').Strategy();
var session=require('express-session');
app.use(express.session({secret:"flibbertygibbit"}));
app.use(cookieParser());
app.use(passport.initialize());
app.use(passport.session());
app.use(bodyParser.json());
passport.use(new LocalStrategy(
{usernameField: 'user.email',
passwordField: 'user.password',
passReqToCallback: true
},
function(username,password,done){
console.log("am here"+username+" "+password);
}
))
app.post('/loginUser',passport.authenticate('local'));
The problem i face is the Local strategy isnot being called at all and all I get Typerror: Local strategy requires a verify callback. I ain't sure where i went wrong, being novice at it. Please help.

The error you're getting is caused by this:
var LocalStrategy=require('passport-local').Strategy();
^^
You're calling the Strategy class without any arguments, so this results in the error. You want to store a reference to the class itself, like this:
var LocalStrategy=require('passport-local').Strategy;
Also, because you're setting passReqToCallback : true, the verification callback will take four arguments, not three. It should look like this:
function(req, username, password, done) { ... }

Related

How to sens and access parameters with POST method

I'm creating an authent form for my web page with Javascript and using Vue JS on client side and NodeJS with ExpressJS on server side.
On server side I writed my post method :
server.app.post("/login", function(req, res) {
console.log(req.body.username);
})
On client side, I have my form on my html link to a Vue instance:
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="authent">
<p>Username :</p>
<input type="text" name="username" v-model="username" required>
<p>Pwd :</p>
<input type="password" name="password" v-model="password" required>
<button v-on:click="authent">Login</button>
</div>
<script src='/authent/vue.js'></script>
<script src='/authent/vue-resource.min.js'></script>
<script src="authent.js"></script>
</body>
</html>
window.onload = function () {
var authent = new Vue({
el: '#authent',
data: {
username: null,
password: null
},
methods: {
authent: function() {
try {
this.$http.post('/login', {"username": authent.username, "password": authent.password})
.then(function(response) {
console.log(response.body);
})
} catch (e) {
console.log(e);
}
}
}
})
}
Apparently I wrongly send parameters in vue instance because on server side the req.body is undefined.
EDIT
Parameters are sent, but I don't know how I can access them in my post method on server side.
you send it through ajax way. and you probably also send it as json object not a real post data. in express you should write (to have a json parser)
app.use(express.json());
and just to be safe. add a body parser too :-)
app.use(express.urlencoded({ extended: true }))
you probably will need it too sooner or latter
just add the above middlewares
I'm not familiar with Vue, but can you try to use this.username instead of authent.username ?
In your devTools, can you see that params has been seend ? To be sure that's a front-end issue.

Cannot read post parameters from req.body in Express.js 4.13.x

Objective: I'm new to Node.js and Express.js framework. Currently I'm writing a small app using IONIC framework where I trying to pass user basic details like FirstName, LastName to node.js server as a matter of first step. Then once I read the data I'm planning to save the data in the database.
Issue: Currently when I pass the details (in this case just FirstName for testing purpose) through POST request from my app to the node js server and when i try to access the FirstName using req.body.FirstName, the server returns "undefined".However when I use console.log(req.body) it returns the value for eg., { '{"FirstName":"test"}': '' }.
I'm not sure where did I miss. I suppose I referred a lot of links thru Google, nothing seems to be working out. It might be a simple thing, but it is bothering me lot and I'm wasting time to find the solution.
Configuration:
Express.js - 4.13.3
I've tried different combination based on the related links for this issue. Nothing seems to be working. Any guidance or advise will be really helpful as I got struck in this.
serverapp.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'GET,POST');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
app.post('/', function(req, res) {
console.log("Hi from server", req.body);
console.log("Hi this is key value", req.body.FirstName); // this throws error as undefined
});
var server = app.listen(8100, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
Code snippet from Controllers.js - Post request is sent via this.
var url = 'http://localhost:8100'
var request = $http.post(url,
{'FirstName': $scope.Model.FName}, {headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}});
Rego.html file
<form name="tab-Registration.form">
<div class="list" align="left">
<label class="all_page_bgColor" align="left">
<input type="text" name="FName" placeholder="First Name" ng-model="Model.FName" class="all_page_bgColor" align="left">
</label>
<label class="all_page_bgColor" align="left">
<input type="text" name="LName" placeholder="Last Name" ng-model="Model.LName" class="all_page_bgColor" align="left">
</label>
<label class="all_page_bgColor" align="left"> <!-- class="item item-input" -->
<input type="text" name="Email" placeholder="Email" ng-model="Model.Email" class="all_page_bgColor" align="left">
</label>
<label class="all_page_bgColor" align="left">
<input type="text" name="PhoneNo" placeholder="Phone" ng-model="Model.PhoneNo" class="all_page_bgColor" align="left">
</label>
</div>
<div align = "center">
<button class="button button-assertive" ng-click="submit()">Submit</button>
</div>
</form>
This object { '{"FirstName":"test"}': '' } has only one key which is {"FirstName":"test"} and the value is empty string. Actually the whole object is the key of first value.
Object must be like this: {"FirstName":"test"}
But i don't know how things end up like this. You have FName in your form but you get this, and I don't know what this IONIC framework is and how it works. I think it's better to start with experimenting with express.js then switch to higher level frameworks.
I've resolved this. The solution is to use transformRequest while sending the request to the server for URL encoded data, coz the request send to server by default sends Json object. And when you want to over-ride that, you have to use transformRequest
$http({
method: 'POST',
url: url,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
for(var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data: {
FirstName: $scope.Model.FName}

Mongoose $push from HTML Form not working

Can anyone tell me what am I doing wrong.
My HTML Form:
<form action="/user/:id" method="put">
<div class="form-group">
<label>Miles</label>
<input type="text" class="form-control" name="miles">
</div>
<button type="submit" class="btn btn-warning btn-lg">Login</button>
</form>
My Express Route:
app.put('/user/:id', function(req, res) {
User.findById(req.body.params.id, function(err, user) {
if (err)
res.send(err);
console.log(user.id);
User.findByIdAndUpdate(
user.id,
{$push: {"milesLog": {miles: req.body.miles}}},
{safe: true, upsert: true},
function(err, model) {
console.log(err);
},
res.json(user)
);
Posting from my HTML form I get the following Error:
Cannot GET /user?miles=66&activity=asdasd
But When I test this through POSTMAN it works:
What am I doing wrong. Why doesn't it work from my HTML Form?
The route doesn't match, you have this URL
/user?miles=66&activity=asdasd
and then this route
app.put('/user/:id', ....
that route is looking for something like this
/user/66
it doesn't look for querystrings, that would be
app.put('/user', function(req, res) {
var miles = req.query.miles;
var activity = req.query.activity;
and unless you have a really good reason for using PUT request, you should change that to use GET instead.
Also, <form action="/user/:id" ... isn't a valid URL, you can't have colons in the URL, and you seem to have misunderstood a little, the :id in your route matches anything, as long as it's a valid route, so it will match
/user/frank
/user/77
/user/something?querystring
etc. and then you can access that inside the route
app.get('/user/:id', function(req, res) {
var user = req.params.id; // returns "frank" etc
There is no "PUT" verb in html forms, while you are implementing it like this:
<form action="/user/:id" method="put">
You have to use method="POST" in html form and change your route to:
app.post('/user/:id')
It's not a bad thing to use such method.
However if you are developing a front-end application it's common to use XMLHttpRequest object which has "PUT" verb, and your route will work just fine.

Undefined Value For Response Body in Node.js in an Exports Function.

I have a controller accessed from a route through a
router.post('/human',human.create);
human is imported through its controller file which contains the following :
var config = require(__dirname + '/../config/config'),
logger = require(__dirname + '/../lib/logger'),
util = require(__dirname + '/../helpers/util');
exports.create = function(request, response, next){
response.send({
id: "human_103tsG2eZvKYlo2CW5yEDyUe",
firstName: "Patricia",
middleName: null,
lastName: "Cesar",
sex: "Female",
birthdate: null
});
};
Inside this create function, I can do
console.log(request);
And a humongous JSON object will apear in the terminal, including the attribute I need : body.
However, when I do, console.log(request.body), it goes undefined.
Am I missing a particular functionality of Node or Express that needs to be coded out?
I guess you are using the express 4.x which decoupled lots of middleware packages, as #shredmill metioned, you should use
bodyParser = require ('body-parser')
...
app.use(bodyParser.json()); //i found this works for me comparing to use bodyParser()
req.body is not pre-parsed for you automatically. You should explicitly use the connect.json() middleware for this:
var connect = require('connect');
router.post('/human', connect.json(), human.create);

CompoundJS and passport support

I'm facing this problem with compound passport. I've already followed the steps from the guide but I cannot get this working when I try to access /auth/github.
Any tips?
GET /auth/github controller: auth action: github
Params: {"controller":"auth","action":"github"}
>>> perform github
Error: Undefined action auth#github(/auth/github)
at Object.FlowControl.call.context.innerNext (/Users/javiermanzanomorilla/Development/workspace/authapp/node_modules/compound/node_modules/kontroller/lib/flow-control.js:67:27)
at Array.FlowControl.call.collection.forEach.queue.push.ctl.context.inAction [as 1] (/Users/javiermanzanomorilla/Development/workspace/authapp/node_modules/compound/node_modules/kontroller/lib/flow-control.js:139:28)
at run (/Users/javiermanzanomorilla/Development/workspace/authapp/node_modules/compound/node_modules/kontroller/lib/flow-control.js:102:27)
at Array.FlowControl.call.action [as 0] (/Users/javiermanzanomorilla/Development/workspace/authapp/node_modules/compound/node_modules/kontroller/lib/flow-control.js:60:13)
at run (/Users/javiermanzanomorilla/Development/workspace/authapp/node_modules/compound/node_modules/kontroller/lib/flow-control.js:102:27)
at FlowControl.call.compiledAction.(anonymous function) (/Users/javiermanzanomorilla/Development/workspace/authapp/node_modules/compound/node_modules/kontroller/lib/flow-control.js:90:9)
at Controller.call (/Users/javiermanzanomorilla/Development/workspace/authapp/node_modules/compound/node_modules/kontroller/lib/flow-control.js:49:16)
at Controller.call (/Users/javiermanzanomorilla/Development/workspace/authapp/node_modules/compound/node_modules/kontroller/lib/flow-control.js:93:10)
at Controller.perform (/Users/javiermanzanomorilla/Development/workspace/authapp/node_modules/compound/node_modules/kontroller/lib/flow-control.js:18:10)
at ControllerBrigde.callControllerAction (/Users/javiermanzanomorilla/Development/workspace/authapp/node_modules/compound/lib/controller-bridge.js:95:9)
i think that you havn't init the passport.
if you are using compound-passport you have to initialize it by calling the init function in config/environment.
var pass_connect=require('compound-passport');
app.configure(function(){
....
//init the compound passport
pass_connect.init(compound);
app.use(app.router);
});
case if you want to initialize it manualy you have to call those two methods :
var passport=require('passport');
var Strategy = require('passport-github').Strategy;
passport.use(new Strategy({
clientID: conf.github.clientID,
clientSecret: conf.github.secret,
callbackURL: conf.baseURL + 'auth/github/callback'
}, exports.callback));
app.get('/auth/github',
passport.authenticate('github'));
app.get('/auth/github/callback',
passport.authenticate('github', { failureRedirect: '/' }),
exports.redirectOnSuccess);
sorry for my english.

Categories

Resources