I'm trying to do twitter oauth in nodejs using passportjs but getting error
Cannot GET /auth/twitter/callback?oauth_token=alksdkalsjdsjd23232378skjdfjsdhf&oauth_verifier=234jjh23j4k234k23h4j2h342k34hj
Here is my node js code
var express = require('express')
, passport = require('passport')
, util = require('util')
, GoogleStrategy = require('passport-google').Strategy
, TwitterStrategy = require('passport-twitter').Strategy;
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(obj, done) {
done(null, obj);
});
passport.use(new TwitterStrategy({
consumerKey: 'xxxxxxxxxxxxxxxxxxxx',
consumerSecret: 'xxxxxxxxxxxxxxxxxxxxxxxxxx',
callbackURL: 'http://127.0.0.1:3000/auth/twitter/callback'
},
function(token, tokenSecret, profile, done) {
process.nextTick(function () {
return done(null, profile);
});
}
));
var app = express();
// configure Express
app.configure(function() {
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.logger());
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.session({ secret: 'keyboard cat' }));
// Initialize Passport! Also use passport.session() middleware, to support
// persistent login sessions (recommended).
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(express.static(__dirname + '/../../public'));
});
app.get('/', function(req, res){
res.render('index', { user: req.user });
});
app.get('/login', function(req, res){
res.sendfile('./views/auth.html');
});
app.get('/auth/twitter', passport.authenticate('twitter'));
app.get('auth/twitter/callback',
passport.authenticate('twitter', { successRedirect: '/success',
failureRedirect: '/login' }));
app.get('/success', function(req, res){
res.send("success logged in");
});
app.listen(process.env.PORT || 3000);
EDIT
There is missing / in auth/twitter/callback route definition.
Also for the routers /auth/twitter and auth/twitter/callback, passport.authenticate() as middleware will do the authentication, and you should have route handling functions.
So the definition of your routes should look something like:
app.get('/auth/twitter',
passport.authenticate('twitter'),
function(req, res) {}); // empty route handler function, it won't be triggered
app.get('/auth/twitter/callback',
passport.authenticate('twitter', {
successRedirect: '/success',
failureRedirect: '/login' }),
function(req, res) {}); // route handler
You don't need the empty route handler function(req, res) {} - you can just leave the argument out and express will understand you don't plan on ever using the handler
Related
I'm using React Router with Passport.js to set up Facebook login. I've set up the express routes and passport config, but every time I hit the
<a href="/api/auth/facebook"> link on my client side, it makes a request to RR because of my express app with this line:
app.get('/*', function(req, res) {
res.sendFile(path.resolve(__dirname, '../client', 'build', 'index.html'))
});
As I am making a call to the server side route, it returns this error:
Warning: [react-router] Location "/api/auth/facebook" did not match any routes
How can I bypass React Router for this one particular route?
my user_routes.js file looks like:
'user strict';
var bodyparser = require('body-parser');
var User = require('../models/User.js');
module.exports = function loadUserRoutes(router, passport) {
router.use(bodyparser.json());
router.get('/auth/facebook', passport.authenticate('facebook', {
session: false,
successRedirect: '/chat',
failureRedirect: '/'
}));
router.get('/auth/facebook/callback', passport.authenticate('facebook', {
session: false,
successRedirect: '/chat',
failureRedirect: '/'
}));
router.post('/sign_up', passport.authenticate('local-signup', { session: false}), function(req, res) {
res.json(req.user);
});
router.post('/sign_in', passport.authenticate('local-login', { session: false}), function(req, res) {
res.json(req.user);
});
router.get('/signout', function(req, res) {
req.logout();
res.end();
});
//get auth credentials from server
router.get('/load_auth_into_state', function(req, res) {
res.json(req.user);
});
// get usernames for validating whether a username is available
router.get('/all_usernames', function(req, res) {
User.find({'local.username': { $exists: true } }, {'local.username': 1, _id:0}, function(err, data) {
if(err) {
console.log(err);
return res.status(500).json({msg: 'internal server error'});
}
res.json(data);
});
})
};
In express routes are matches in the order they get defined.
So before your /* route you need something to handle api requests.
app.get('/api/auth/facebook', passport.authenticate('facebook'))
app.get('/*', function(req, res) {
res.sendFile(path.resolve(__dirname, '../client', 'build', 'index.html'))
});
I'm using Cloud 9 to setup a basic social media website and I am having trouble with registration and authentication of users. I'm using Node.js, express and passport for authentication, and mongoDB as a database.
// PASSPORT Setup //
app.use(require("express-session")({
secret: "I am the best",
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());
// INDEX Page
app.get("/", function(req, res) {
res.render("landing-page");
});
// REGISTER NEW
app.get("/register", function(req, res) {
res.render("user/register");
});
// REGISTER CREATE
app.post("/register", function(req, res) {
var user = req.body.user;
var newUser = new User({
username: user.email,
firstName: user.firstName,
lastName: user.lastName,
});
User.register(newUser, user.password, function(err, user) {
if(err) {
console.log(err);
return res.render("user/register");
}
passport.authenticate("local")(req, res, function() {
res.redirect("/");
});
});
});
// Login routes
app.get("/login", function(req, res) {
res.render("login");
});
app.post("/login", passport.authenticate("local", {
successRedirect: "/",
failureRedirect: "/login"
}) , function(req, res) {
});
// Logout route
app.get("/logout", function(req, res) {
req.logout();
res.redirect("/");
});
However whenever I run this, when I sign up a new user, it gives me a webpage with just "Bad Request", however the user is created in the database.
Look at this answer; the bad request is not a problem with your passport method: that indicates the request you try to make is not correct:
Did you set the head at: Content-Type: application-json?
Also update the bodyParser to the last version. This solved a similar problem I had.
I have an application node js using express for authentication via facebook but the url /auth/facebook/callback does not load.
Dependencies version:
Express: 4.13.3
Passport 0.3.0
Passport-facebook 2.0.0
app.js
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
passport.use(new FacebookStrategy({
clientID: '806175282757975',
clientSecret: '*************',
callbackURL: "http://localhost:3000/auth/facebook/callback"
},
function(accessToken, refreshToken, profile, done) {
process.nextTick(function () {
return done(null, profile);
});
}
));
app.use(function(req,res,next){
req.passport = passport;
next();
});
app.use('/', routes);
app.use('/users', users);
module.exports = app;
routes/index.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
router.get('/auth/facebook', function(req, res, next){
req.passport.authenticate('facebook')(req, res, next);
});
router.get('/auth/facebook/callback', function(req, res, next){
req.passport.authenticate('facebook', { successRedirect: '/',
failureRedirect: '/login' });
});
module.exports = router;
No error is returned on console.
In routes/index.js in /auth/facebook/callback route you forgot about calling authenticate method with req, res, next arguments. That is why your application was stuck ('next' callback was never called).
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
router.get('/auth/facebook', function(req, res, next){
req.passport.authenticate('facebook')(req, res, next);
});
router.get('/auth/facebook/callback', function(req, res, next){
req.passport.authenticate('facebook', {
successRedirect: '/',
failureRedirect: '/login' }
)(req, res, next); // missing function call
});
module.exports = router;
I have a persistent problem with Passport.js in my Express.js small application : whatever I put in the LocalStrategy, I'm always redirected to the failureRedirect, apparently without even pass by the LocalStrategy...
What did I wrong ? And how can I print/display the largest error log to follow the execution ?
var express = require('express'),
passport = require('passport'),
LocalStrategy = require('passport-local').Strategy;
http = require('http'),
path = require('path'),
mysql = require('mysql'),
flash = require('connect-flash');
var app = express();
// SQL connexion
var sqlInfo = {
host: 'localhost',
user: 'root',
password: '',
database: 'mex'
};
global.client = mysql.createConnection(sqlInfo);
client.connect(function(err) {
if(err)
console.log(err);
});
app.configure(function(){
app.set('views', __dirname+'/views');
app.set('port', process.env.PORT || 85);
//app.engine('ejs', engine);
app.use(express.static('public'));
app.use(express.cookieParser());
app.use(express.bodyParser());
// 1 - Session express
app.use(express.session({ secret: 'secretpass' }));
// 2 - Init et session Passeport
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use(express.logger());
app.use(app.router);
});
// Simple logger
app.use(function(req, res, next){
console.log('%s %s', req.method, req.url);
next();
passport.use(new LocalStrategy(
function(username, password, done) {
console.log("localstrategy ---");
var user = {username: 'w#j.fr', password: 'pwd'};
return done(null, user);
}));
passport.serializeUser(function(user, done) {
// JUST 4 TEST
done(null, user);
});
passport.deserializeUser(function(user, done) {
// JUST 4 TEST
done(null, user);
});
// Home
app.get('/', function(req, res){
//check user session value, is logged in
if(req.user)
res.render('menu_log.ejs', function(err, html){
var data = {
title: 'Home',
menu: html
//req.user['Prenom'] -- à afficher
};
res.render('index.ejs', data);
console.log("index logué");
});
else
res.render('menu_nolog.ejs', function(err, html){
var data = {
title: 'Home',
menu: html
};
res.render('index.ejs', data);
console.log("index PAS logué");
});
});
// Passport's authentication
app.post('/login',
passport.authenticate('local', { successRedirect: '/',
successFlash: 'Bienvenue !',
failureRedirect: '/wrong',
failureFlash: "Email ou mot de passe incorrect." })
);
app.get('/logout', function(req, res){
req.logout();
res.redirect('/');
})
.get('/inscription', function(req, res){
res.render('menu_nolog.ejs', function(err, html){
var data = {
title: 'Register',
menu: html
};
res.render('inscription.ejs', data);
});
});
http.createServer(app).listen(app.get('port'), function () {
console.log('Express server listening on port ' + app.get('port'));
});
LocalStrategy requires two parameters (either passed as POST data, or in a query string) to exist: username and password. If you're not passing those two, Passport doesn't even bother to call the strategy handler.
The field names are configurable by passing an object as first argument to the LocalStrategy constructor:
passport.use(new LocalStrategy({
usernameField : 'username',
passwordField : 'password'
}, function(username, password, done) { ... }));
I am trying to use Passport as an authentication middleware with Express - and Angular, if it matters. I have just started to know these frameworks and I experiment with a simple test login in the app. These are the relevant code snippets in my root/app.js that should do the login method:
var express = require('express'),
routes = require('./routes'),
api = require('./routes/api'),
passport = require('passport'),
LocalStrategy = require('passport-local').Strategy;
...
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.static(__dirname + '/public'));
app.use(passport.initialize());
app.use(app.router);
});
...
// Authentication with Passport.js
var testUser = {
username: 'patrik',
password: '123'
}
passport.use(new LocalStrategy(
function(username, password, done) {
if(username == testUser.username) {
if(password == testUser.password) {
return done(null, username);
} else {
return done(null, false, { message: 'Incorrect password.' });
}
} else {
return done(null, false, { message: 'Incorrect username.' });
}
}
));
...
app.post('/login',
passport.authenticate('local', { successRedirect: '/',
failureRedirect: '/login',
failureFlash: true })
);
Here is my template code in index.jade:
form(method='post',action='/login')
div
label Username:
input(type='text',name='username')
div
label Password:
input(type='password',name='password')
div
input(type='submit',value='Log in')
And my problem is that if I try to post, I get this response from the browser:
Response
Cannot POST /login
You have to update some of express and passport requirements for this to work. Such as session, failureflash messages, serialize and deserialize. Here is updated code snippet for you. first you have to install "connect-flash" for this line of codes "failureFlash : true". But it will work without flash.
npm install connect-flash
var express = require('express'),
routes = require('./routes'),
api = require('./routes/api'),
passport = require('passport'),
LocalStrategy = require('passport-local').Strategy,
flash = require('connect-flash');
Then update express environments:
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.static(__dirname + '/public'));
app.use(express.cookieParser());
// required for passport
app.use(express.session({ secret: 'my secret'}));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
});
// Authentication with Passport.js
var testUser = {
username: 'patrik',
password: '123'
}
passport.use(new LocalStrategy(
function(username, password, done) {
if (username === testUser.username && password === testUser.password) {
return done(null, {username: username});
} else {
return done(null, {username: 'username or password incorrect!'});
}
return done(null, false);
}
));
passport.serializeUser(function(user, done) {
done(null, user.username);
});
passport.deserializeUser(function(username, done) {
done(null, {username: username});
});
app.get('/', routes.index);
app.post('/login',
passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/login',
failureFlash: true })
);
And here is a little update for your routes/index.js file:
exports.index = function(req, res){
var user = '';
if(req.session.passport.user !== undefined) user = req.user.username;
res.render('index', {title: user});
};
I hope these will help you to understand login with passport.