I'm making a Facebook login with Express, mongoose and passport / passport-facebook modules for nodejs.
I want to handle with a controller who i created for authenticate. When i activate the server, trigger that message on terminal:
if (!verify) { throw new TypeError('OAuth2Strategy requires a verify callback
^
TypeError: OAuth2Strategy requires a verify callback
This is my code:
userController
var mongoose = require('mongoose');
var passport = require('passport');
var FacebookStrategy = require('passport-facebook').Strategy;
var Account = require('../models/accounts');
var Project = require('../models/projects');
var Message = require('../models/messages');
var Follow = require('../models/follows');
var apiKeys = require('../apiKeys');
{more code}
fbAuth : function(access_token, refresh_token, profile, done){
console.log("*************");
console.log("entra en fbAuth");
console.log("*************");
Account.findOne({'providerId' : profile.id}, function(err, user){
if(err){
return done(err);
}
if(user){
return done(null, user);
}
else{
var newUser = new Account({
emailAccount : profile.emails[0].value,
provider : profile.provider,
providerId : profile.id,
username : profile.name.givenName,
});
newUser.save();
}
});
passport.authenticate('facebook',{
successRedirect : '/user',
failureRedirect : '/'
});
},
fbAuthSuccess : function (req, res){
passport.authenticate('facebook', {
successRedirect : '/user',
failureRedirect : '/'
});
},
route
router.get('/facebook', controller.fbAuth);//passport.authenticate('facebook', { scope : 'email' }));
router.get('/facebook/callback', passport.authenticate('facebook', {
successRedirect : '/user',
failureRedirect : '/'
});
app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var morgan = require('morgan');
var mongoose = require('mongoose');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var FacebookStrategy = require('passport-facebook').Strategy;
var session = require('express-session');
var socket = require('socket.io');
var apiKeys = require('./apiKeys');
var app = express();
{more code}
passport.use(new LocalStrategy(Account.authenticate()));
passport.serializeUser(Account.serializeUser());
passport.deserializeUser(Account.deserializeUser());
//social facebook
passport.use(new FacebookStrategy({
clientID: apiKeys.facebook.appID,
clientSecret: apiKeys.facebook.appSecret,
callbackURL: apiKeys.facebook.callbackUrl,
'profileFields': ['id', 'displayName', 'email', 'name'],
}));
You need to add a verify callback, your controller.fbAuth as a second argument to passport.use. The router.get('/facebook should have passport.authenticate('facebook') as its second argument. You can follow the example on passports docs.
Related
I want to make authentication function with Passport.js+Express.
But If I run this code, I receive failure result and null in 'req.user'.
I want to find the problem, but console.log() in localStrategy is not called when I was using passport.authenticate(). I don't know where I have to fix.
How can I fix this code to get proper function?
-app.js
var express = require('express');
var bodyparser=require('body-parser');
var path = require('path');
var cookieParser = require('cookie-parser');
var passport = require('passport'); //passport module add
var localStrategy = require('passport-local').Strategy;
var cookieSession=require('cookie-session');
var index = require('./index.js');
var app=express();
app.use(cookieParser());
app.use(express.static(__dirname+'/views'));
app.use(cookieSession({
keys : ['login'],
cookie : {maxAge:1000*60*60}
}));
app.set('views',__dirname+'/views');
app.set('view engine','html');
app.engine('html',require('ejs').renderFile);
app.use('/',index);
app.listen(8000,function(){
console.log('server started');
});
module.exports=app;
-index.js
var express = require('express');
var router = express.Router();
var bodyparser=require('body-parser');
var crypto=require('crypto');
var passport=require('passport');
var localStrategy=require('passport-local').Strategy;
var mysql=require('mysql');
var config={
host : 'localhost',
port : 3306,
user : 'root',
password : 'xxxxxx',
ssl : true
};
router.use(bodyparser.json());
router.use(passport.initialize());
router.use(passport.session());
const conn = new mysql.createConnection(config);
conn.connect(function(err){
if(err){
console.log('Cannot Connect to database : ');
throw err;
}
else{
console.log('Success to connect database');
}
});
passport.use(new localStrategy({
usernameField : 'username',
passwordField : 'password',
},function(req,username,password,done){
conn.query('USE Database');
conn.query('select userID as username, userPWD as password from UserTable where userID=?',[username],function(err,userinfo,fields){
if(err){
return done(err);
}
else{
if(username==userinfo[0].username){
var encryptHash=crypto.createHash('sha512').update(password);
if(encryptHash===password){
return done(null,userinfo[0]);
}
console.log('login succeed');
return done(null,userinfo[0]);
}
else{
return done(null,false);
}
}
});
})
);
passport.serializeUser((user,done)=>{
console.log("hello2");
done(null, user.username);
});
passport.deserializeUser((id,done)=>{
console.log("hello");
var sql='select userID as username, userPWD as password from UserTable where userID=?';
conn.query(sql,[id],(err,userinfo,fields)=>{
if(err){
console.log("error 발생 : "+err);
res.status(500).send("Internal Server Error");
}
else{
if(userinfo[0].username==id){
done(null,userinfo[0]);
}
}
});
});
router.get('/',function(req,res,next){
console.log('homepage');
res.render('index');
});
router.post('/login',passport.authenticate('local',{failureRedirect:'/',successRedirect:'/main'}));
module.exports=router;
You should check the "req" param inside
function(req,username,password,done)
may be this function takes only three parameters
**http://www.passportjs.org/packages/passport-local/**
you should check what you get on post request through this `req` using this function
my app.js is
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var flash = require('connect-flash');
var session = require('express-session');
var passport = require('passport');
app.set('views', __dirname+'/views');
app.set('view engine', 'ejs');
app.use(bodyParser());
app.use(cookieParser());
app.use(session({secret : 'somthing'}));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
app.use(function(req, res, next){
res.locals.message = req.flash();
console.log(res.locals);
next();
});
app.use(require('./controller/router'));
// Default Controller Come Here
app.listen(3000, function(){
console.log('Running');
})
router.js is
var express = require('express');
var router = express.Router();
router.use('/', require('./home'));
router.use('/login', require('./login'));
router.use('/user', require('./user'));
module.exports=router;
passport.js (inside of config folder)
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var User = require('../model/users');
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
done(err, id);
});
passport.use(new LocalStrategy(function(username, password, done){
if(username == "test#test.com")
/* hardcore check username and password */
{
if(password=="123")
{
var result = { id : 1, fullname : "james", username : "jamesjoel"};
console.log("Success");
return done(result, true);
}
return done(null, false, { message : "Incorrect Passwordtttt"});
}
return done(null, false, { message : "Incorrect Username and password"});
}
));
module.exports=passport;
and finaly my login.js controller is
var passport = require('../config/passport');
var express = require('express');
var router = express.Router();
router.post('/', passport.authenticate('local', {
successRedirect: '/user',
failureRedirect: '/login',
failureFlash: true
})
);
router.get('/', function(req, res){
console.log(req.flash());
res.render('login', { msg : req.flash()});
});
module.exports=router;
but when i send correct username and password it show in console "success" and show [Object Object] and successRedirect not working infact i wrote somthing on .serializeUser() and .deserializeUser() its also not showing on console....
so please help me for this .....
done is a callback and it takes first argument as an error. But in your case after success still you are passing value as error try to make it null like this return done(null,result, true)
if(password=="123"){
var result = { id : 1, fullname : "james", username : "jamesjoel"};
console.log("Success");
return done(null,result, true);
}
I'm a newbie in Node.js and trying to use API token to access Grafana.
And I created one API token by following instruction from Grafana page.
However, I don't know how to make API calls from my code of node.js to access my local server of grafana page. Also, I have a local login-page by using mongoDB to manage users.
How can I make Node.js API calls to access my local server of grafana page?
Please help me out here.. I'm having hard time on this..
If you want me to show code, I can edit here..
EDIT:
This is my whole code for app.js
var io = require('socket.io');
var express = require('express');
var app = express();
var redis = require('redis');
var sys = require('util');
var fs = require('fs');
//Added for connecting login session
var http = require('http');
var server = http.createServer(app);
var path = require('path');
var mongoose = require('mongoose');
var passport = require('passport');
var session = require('express-session');
var flash = require('connect-flash');
var async = require('async');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
//Adding grafana
var request = require('request');
//Connecting Database (MongoDB)
mongoose.connect("my mongoDB private address");
var db = mongoose.connection;
db.once("open",function () {
console.log("DB connected!");
});
db.on("error",function (err) {
console.log("DB ERROR :", err);
});
//Setting bcrypt for password.
var bcrypt = require("bcrypt-nodejs");
//Setting userSchema for MongoDB.
var userSchema = mongoose.Schema({
email: {type:String, required:true, unique:true},
password: {type:String, required:true},
createdAt: {type:Date, default:Date.now}
});
userSchema.pre("save", function (next){
var user = this;
if(!user.isModified("password")){
return next();
} else {
user.password = bcrypt.hashSync(user.password);
return next();
}
});
//setting bcrypt for password.
userSchema.methods.authenticate = function (password) {
var user = this;
return bcrypt.compareSync(password,user.password);
};
//Setting User as userSchema.
var User = mongoose.model('user',userSchema);
io = io.listen(server);
//Setting middleware for login format.
app.set("view engine", 'ejs');
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
app.use(methodOverride("_method"));
app.use(flash());
app.use(session({secret:'MySecret', resave: true, saveUninitialized: true}));
app.use(passport.initialize());
app.use(passport.session());
//Initializing passport.
passport.serializeUser(function(user, done) {
//console.log('serializeUser()', user);
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
//console.log('deserializeUser()', user);
User.findById(id, function(err, user) {
done(err, user);
});
});
var username_tmp = '';
var global_username = ''; //Global variable for username to put in the address
var pass = '';
//Initializing passport-local strategy.
var LocalStrategy = require('passport-local').Strategy;
passport.use('local-login',
new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
User.findOne({ 'email' : email }, function(err, user) {
if (err) return done(err);
if (!user){
req.flash("email", req.body.email);
return done(null, false, req.flash('loginError', 'No user found.'));
}
if (!user.authenticate(password)){
req.flash("email", req.body.email);
return done(null, false, req.flash('loginError', 'Password does not Match.'));
}
var email_address = req.body.email;
username_tmp = email_address;
var username = email_address.substring(0, email_address.lastIndexOf("#"));
global_username = username;
pass = req.body.password;
return done(null, user);
});
}
)
);
//Check whether it is logged in or not.
//If it is not logged in(Session is out), it goes to login page
//If it is logged in(Session is still on), it goes directly to status.html
app.get('/', loggedInCheck);
app.get('/login', function (req, res) {
res.render('login/login',{email:req.flash("email")[0], loginError:req.flash('loginError')});
});
//Accessing to MongoDB to check to login or not
app.post('/login',
function (req,res,next){
next();
}, passport.authenticate('local-login', {
successRedirect : '/status',
failureRedirect : '/login',
failureFlash : true
})
);
//Creating new account
app.get('/users/new', function(req,res){
res.render('users/new', {
formData: req.flash('formData')[0],
emailError: req.flash('emailError')[0],
passwordError: req.flash('passwordError')[0]
}
);
});
//Calling status.html
app.get('/status', isLoggedIn, function(req, res){
var user_temp = {user: ''};
user_temp.user = global_username;
res.render('status/status', user_temp);
//res.redirect('/status.html?channel=' + global_username);
});
app.get('/grafana', isLoggedIn, function(req, res){
console.log('Accessing to grafana');
res.redirect('http://localhost:8080');
});
request.get('http://localhost:8080',{
auth: {
bearer: 'TOKEN HERE'
}
});
server.listen(4000);
Edited more
app.get('/grafana', isLoggedIn, function(req, res){
console.log('Accessing to grafana');
var url = 'http://localhost:8080/api/dashboards/db/test';
request.get(url,{
auth: {
bearer: 'API token from Grafana page'
}
});
res.redirect(url);
});
Thank you..
The API calls are made with HTTP requests. You can use the request package from npm.
From the docs:
You use the token in all requests in the Authorization header, like this:
GET http://your.grafana.com/api/dashboards/db/mydash HTTP/1.1
Accept: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
Example (I'm using request-promise but you can use whatever you want):
let request = require('request-promise');
let url = `http://your.grafana.com/api/dashboards/db/mydash`;
//Obviously replace this with your token
let myToken = `eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk`;
request.get(url).auth(null, null, true, myToken).then(res=> { ... });
// or
request.get(url, {
auth: {
bearer: myToken
}
}).then(res=> { ... });
im struggled with this problem like more then 40 hours and sill don't know how to solve this, the problem is a little big to explain but i will try my best, im a little newbie with Node.Js and mongo stuffs so forgive me any stupid mistake.
I followed the book Mean Stack and the problem appears when i started this tutorial to do the autentication with auth, i am at the beginning doing the local authentication without any social at the moment.
folder structure
so basicly i set the server like this:
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
var mongoose = require('./config/mongoose');
var express = require('./config/express');
var db = mongoose();
var app = express();
app.listen(3000);
module.exports = app;
console.log("running at port 3000");
this is the ./config/mongoose
var config = require('./config');
var mongoose = require('mongoose');
var connectionString = "mongodb://localhost:27017/ShareIdea"
module.exports = function(){
mongoose.Promise = global.Promise;
var db = mongoose.connect(connectionString);
require('../app/models/user.server.model');
return db;
};
the required user.server model
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
var Schema = mongoose.Schema;
var UserSchema = new Schema({
local : {
email : String,
password : String,
},
facebook : {
id : String,
token : String,
email : String,
name : String
},
twitter : {
id : String,
token : String,
displayName : String,
username : String
},
google : {
id : String,
token : String,
email : String,
name : String
}
/*firstname:String,
lastname:String,
email:String,
username:String,
password:String,
userChoice: {type: String, possibleValues: ['programmer','inovator']}*/
});
UserSchema.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
UserSchema.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.local.password);
};
mongoose.model('User',UserSchema);
here is the express configuration
var config = require('./config');
var express = require('express');
var passport = require('passport');
var flash = require('connect-flash');
var compress = require('compression');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var bodyParser = require('body-parser');
var morgan = require('morgan');
var methodOverride = require('method-override');
var expressLayouts = require('express-ejs-layouts');
module.exports = function(){
var app = express();
**require('./passport')(passport);**
if(process.env.NODE_ENV === 'development')
{
app.use(morgan('dev'));
}
else if(process.env.NODE_ENV === 'production')
{
app.use(compress());
}
app.use(cookieParser());
app.use(bodyParser.urlencoded({
extended:true
}));
app.use(morgan('dev'));
app.use(bodyParser.json());
app.use(methodOverride());
app.use(session({
saveUninitialized: true,
resave: true,
secret: 'aaaaaaa'
}));
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash());
app.set('views', './app/views');
app.set('view engine','ejs');
app.use(expressLayouts);
require('../app/routes/index.server.routes.js')(app,passport);
require('../app/routes/register.server.routes.js')(app,passport);
require('../app/routes/login.server.routes.js')(app,passport);
require('../app/routes/profile.server.routes.js')(app,passport);
app.use(express.static('./public'));
return app;
}
here in the express is where the problems appear, this line is the main problem at the moment: `require('./passport')(passport);
if i put this code it gives me the problem that i mentioned in the title, if not when i do a POST request with my form it never posts, i have this troubles because i set the structures of my code to a MVC structure like the book and want to adapt the authentication in the tutorial to my code to learn a little,
so basicly im passing the passport to my routes like this:`
register route
var register = require('../../app/controllers/register.server.controller');
module.exports = function(app,passport) {
app.route('/register')
.post(function(req,res){
console.log("HY");
passport.authenticate('local-signup', {
successRedirect : '/profile', // redirect to the secure profile section
failureRedirect : '/register', // redirect back to the signup page if there is an error
failureFlash : true // allow flash messages
})})
.get(register.getPage);
};
Register controller
var User = require('mongoose').model('User');
module.exports = {
getPage: function(req,res){
res.render('./pages/register',{ message: req.flash('signupMessage') });
}
};
and to end here is the passport code:
// config/passport.js
// load all the things we need
var LocalStrategy = require('passport-local').Strategy;
// load up the user model
var User = require('../app/models/user');
// expose this function to our app using module.exports
module.exports = function(passport) {
// =========================================================================
// passport session setup ==================================================
// =========================================================================
// required for persistent login sessions
// passport needs ability to serialize and unserialize users out of session
// used to serialize the user for the session
passport.serializeUser(function(user, done) {
done(null, user.id);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
// =========================================================================
// LOCAL SIGNUP ============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use('local-signup', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) {
// asynchronous
// User.findOne wont fire unless data is sent back
process.nextTick(function() {
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
User.findOne({ 'local.email' : email }, function(err, user) {
// if there are any errors, return the error
if (err)
return done(err);
// check to see if theres already a user with that email
if (user) {
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
} else {
// if there is no user with that email
// create the user
var newUser = new User();
// set the user's local credentials
newUser.local.email = email;
newUser.local.password = newUser.generateHash(password);
// save the user
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
});
}));
};
Ps: Sorry for the long post, i hope i can get a explanation since i want to learn more, when i read the book i felt like the mvc structure adapted by the autor was dificult, but anyways thanks a lot.
if you guys want to not look at this i understand and here is the gitProject:git project
Try this in your user.server.model.js file. Instead of just
mongoose.model('User',UserSchema);
Try this below to have it accessible.
module.exports = {
User : mongoose.model('User', UserSchema)
}
I'm trying to run some basic tests with passport on Node, and when I try to access the route localhost:3000/login I get a Bad request 400. Here is the code:
var express = require('express');
var app = express();
var jwt = require('jsonwebtoken');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(
function(username, password, done) {
var user = {
username: "name",
password: "password123"
}
return done(null, user);
}
));
app.post('/login',
passport.authenticate('local', {session: false}),
function(req, res) {
req.user.name = "Giuan";
res.send(req.user.name);
//res.redirect('/users/' + req.user.username);
});
app.listen(3000, ()=>{
console.log('Running on port 3000');
})
Try this:
var express = require('express');
var app = express();
var jwt = require('jsonwebtoken');
var passport = require('passport');
var bodyParser = require('body-parser');
//if you are getting the info (username and password) through the body
//of the http request you need to use body-parser
app.use(bodyParser());
var LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(
function(username, password, done) {
var user = {
username: "name",
password: "password123"
}
return done(null, user);
}
));
app.use(passport.initialize());
app.post('/login',
passport.authenticate('local', {session: false}),
function(req, res) {
req.user.name = "Giuan";
res.send(req.user.name);
//res.redirect('/users/' + req.user.username);
});
app.listen(3000, ()=>{
console.log('Running on port 3000');
})
Use app.use(passport.initialize()); you haven't initialize passport in your code.
var express = require('express');
var app = express();
var jwt = require('jsonwebtoken');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(
function(username, password, done) {
var user = {
username: "name",
password: "password123"
}
return done(null, user);
}
));
app.use(passport.initialize());
app.post('/login',
passport.authenticate('local', {session: false}),
function(req, res) {
req.user.name = "Giuan";
res.send(req.user.name);
//res.redirect('/users/' + req.user.username);
});
app.listen(3000, ()=>{
console.log('Running on port 3000');
})
I was also facing the same issue and just fixed it by adding usernameField and passwordField keys to the localStrategy options.
new localStrategy({
usernameField: 'email',
passwordField: 'password'
}, function (email, password, done) {
// Do something here
});