I am trying to make a "Connect with Twitter" feature for my website, and it is the first time that I use Passport.js.
I have a problem since a while now : when trying the api, the passport.authenticate function of the /twitter/callback page gets stucks and I can't do anything to solve this problem
I am running my app on my localhost system. Here is my code for the index.js page. The home.ejs just contains a template for EJS where I show the username.
var express = require('express');
var app = express();
const cookieParser = require('cookie-parser');
app.use(cookieParser('thissecretrocks'));
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
const session = require('express-session');
app.use(session({
resave: true,
saveUninitialized: true,
secret: 'bla bla bla'
}));
const mongoose = require('mongoose');
mongoose.connect('mongodb+srv://Something', {useNewUrlParser: true, useUnifiedTopology: true});
const db = {};
db.users = require('./db/users');
const passport = require('passport');
app.use(passport.initialize());
app.use(passport.session());
const Twitter = require('passport-twitter');
var Strategy = require('strategy');
const TwitterStrategy = Twitter.Strategy;
passport.serializeUser(function (user, done) {
done(null, user.id);
});
passport.deserializeUser(function (id, done) {
db.users.findById(id, function (err, user) {
done(err, user);
});
});
passport.use(new TwitterStrategy({
consumerKey: '5KSomethingMx',
consumerSecret: 'tld1Something6M2q',
callbackURL: "http://127.0.0.1:3000/auth/twitter/callback",
},
function(token, tokenSecret, profile, cb) {
console.log(profile);
/*const newUser = new db.users({
twitter: profile.id
});
newUser.save();*/
}
));
app.use('/cdn', express.static('cdn'));
app.get('/', function(req, res) {
res.render('home.ejs', {username: req.user.username});
});
app.get('/fail', function(req, res) {
console.log('FAIL');
res.render('home.ejs', {username: 'req.user.username'});
});
app.get('/auth/twitter', passport.authenticate('twitter'));
app.get('/auth/twitter/callback', passport.authenticate('twitter', { failureRedirect: '/fail' }), function(req, res) {
res.redirect('/');
});
app.listen(3000);
Related
I am creating a login and user registration with Node.js.
the problem is that passport always takes me to failureRedirect and i dont know why
'use strict';
const express = require('express');
const User = require('../../models/User');
const { Router } = require('express');
const router = express.Router();
const passport = require('passport')
router.get('/', (req, res, next) => {
res.render('index');
});
// GET /signup
router.get('/signup', (req, res, next) => {
res.render('signup');
})
// POST /signup
router.post('/signup', passport.authenticate('local-signup', {
successRedirect: '/',
failureRedirect: '/signup',
passReqToCallback: true
}))
// GET /login
router.get('/login', (req, res, next) => {
res.render('login');
});
// POST /login
router.post('/login', passport.authenticate('local-login', {
successRedirect: '/',
failureRedirect: '/login',
passReqToCallback: true
}));
module.exports = router;
This my app.js file
var createError = require('http-errors');
var express = require('express');
var cors = require('cors');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const passport = require('passport')
const session = require('express-session')
const flash = require('connect-flash')
// connection to the DB
require('./lib/connectMongoose');
// require passport
require('./passport/local-auth')
// connection to API
const usersApi = require('./routes/api/users')
const postsRouter = require('./routes/api/posts')
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(cors());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({
secret: 'mysecretsession',
resave: false,
saveUninitialized: false
}))
app.use(flash())
app.use(passport.initialize())
app.use(passport.session())
app.use((req, res, next)=> {
app.locals.registerMessage = req.flash('signupMessage')
app.locals.loginMessage = req.flash('loginMessage')
next();
});
// API routes
app.use('/api/posts', postsRouter);
app.use('/api/users', usersApi);
app.use('/', require ('./routes/api/login'));
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
This is my passport file:
const passport = require('passport');
const localStrategy = require('passport-local').Strategy;
const User = require('../models/User')
//serialize user to save signup
passport.serializeUser((user, done) => {
done(null, user.id)
});
//authenticate the id in the browser
passport.deserializeUser( async(id, done) => {
const user = await User.findById(id)
done(null, user)
});
// receive registration and validate it
passport.use('local-signup', new localStrategy({
usernameField: 'username',
emailField: 'email',
passwordField: 'password',
passReqToCallback: true
} , async (req, email, username, password, done) => {
const user = await User.findOne({ email: email }, { username: username})
if (user) {
return done(null, false, req.flash('signupMessage', 'The email or username is already taken'))
} else {
const newUser = newUser();
newUser.username = username;
newUser.email = email;
newUser.password = newUser.encryptPassword(password);
console.log(newUser)
await newUser.save();
done(null, newUser);
}
}))
passport.use('local-login', new localStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true
}, async (req, email, password, done) => {
const user = await User.findOne({email: email});
if(!user) {
return done(null, false, req.flash('loginMessage', 'No User Found'));
}
if(!user.comparePassword(password)) {
return done(null, false, req.flash('loginMessage', 'Incorrect Password'));
}
return done(null, user);
}));
What I need is that when doing the login it takes me to the home page of the application. Apparently I have some error and that's why it takes me to the login page again but I don't get the error....
I am trying to develop a component that allows users to login to my app using their reddit account by using passport js 0auth strategy.
After setting up my strategy and routes, the /auth/reddit goes to an empty page.
My passport setup code:
require("dotenv").config();
const express = require('express');
const passport = require('passport');
const session = require('express-session');
const RedditStrategy = require('passport-reddit').Strategy;
const app = express();
const PORT = 3000;
const REDDIT_CLIENT_ID = process.env.REDDIT_CLIENT_ID;
const REDDIT_SECRET_KEY = process.env.REDDIT_SECRET_KEY;
passport.use(new RedditStrategy({
clientID: REDDIT_CLIENT_ID,
clientSecret: REDDIT_SECRET_KEY,
callbackURL: "http://localhost:3000/auth/reddit/callback"
},
function(accessToken, refreshToken, profile, done) {
User.findOrCreate({ redditId: profile.id }, function (err, user) {
return done(err, user);
});
}
));
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUserUser((user, done) => {
done(null, user);
});
app.use(session({
secret: 'reddit',
resave: false,
saveUnitialized: false
}))
app.use(passport.initialize());
app.use(passport.session());
app.get('/auth/reddit', function(req, res, next){
req.session.state = crypto.randomBytes(32).toString('hex');
passport.authenticate('reddit', {
scope: ['profile']
})(req, res, next);
});
app.listen(PORT, () => console.log(`Listening on ${PORT}`));
Thanks in advance for any feedback or tips.
i'm using a localhost to test the passport-facebook authentication, i've been trying to implement the Auth and im getting the error mentioned above i've reviewed similar questions but none seem to help me, i've changed my dns address but to no avail,
this is my passport.js code for facebook authentication
const mongoose = require("mongoose");
const FacebookStrategy = require('passport-facebook').Strategy;
const passport = require('passport');
const User = module.exports = mongoose.model('User', facebookSchema)
var facebookSchema = mongoose.Schema
module.exports = function (_passport) {}
//serialize the user for the session
passport.serializeUser(function (user, done) {
done(null, user.id);
});
//deserialize the user
passport.deserializeUser(function (id, done) {
User.findById(id, function (err, user) {
done(err, user);
});
});
passport.use('facebook', new FacebookStrategy({
clientID: 'XXXXXXXXXX',
clientSecret: 'YYYYYYYYYYYYYYY',
callbackURL: " http://localhost:3000/auth/facebook/callback",
enableProof: true,
profileFields: ['id', 'displayName', 'photos', 'email']
},
function (accessToken, refreshToken, profile, done)
{ let newUser = new User();
// set the user's facebook credentials
newUser.facebook.email = profile.emails[0].value,
newUser.facebook.fullName = profile.displayName,
User.findOne({email:newUser.facebook.email }, function(err, user) {
if(!user) {
newUser.save(function(err, newUser) {
if(err) return done(err);
done(null,newUser);
});
} else {
done(null, user);
}
});
}
));
this is my index.js code for initiallizing app
const rfc = require('rfc-3986');
const express = require('express');
const bodyParser = require('body-parser');
var routes = require('./routes/routes'); //importing route
require('./models/userModel')
app = express();
port = 3000;
require("./config/db"); app.get('/success', (req, res) => res.send("You have successfully logged in"));
app.get('/error', (req, res) => res.send("error logging in"));
const passport = require("passport");
app.use(passport.initialize());
app.use(passport.session());
require('./config/passport')(passport);
app.set(rfc)
routes(app, passport);
app.set('view engine', 'ejs')
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended:true}))
app.listen(port,()=>{
console.log('server listening on localhost:' + port)
});
and this is my routes.js for app routing
app.get('/auth/facebook',
passport.authenticate('facebook', {scope:"email"}));
app.get('/auth/facebook/callback',
passport.authenticate('facebook', { failureRedirect: '/login' }),
function(req, res) {
// Successful authentication, redirect home.
res.redirect('/success');`module.exports = function(app, passport) {
app.get('/auth/facebook',
passport.authenticate('facebook', {scope:"email"}));
app.get('/auth/facebook/callback',
passport.authenticate('facebook', { failureRedirect: '/login' }),
function(req, res) {
// Successful authentication, redirect home.
res.redirect('/success');
});
}
});
}
this is the error i get on browser
this is the same error on terminal
So recently I came across a problem, which is happening when i try to authenticate using google oauth2 from mobile, but when i try to authenticate via computer, it works fine. I am using it with passportjs in node/express project.
project link: https://rhubarb-tart-18821.herokuapp.com/
You guys can see code here:
https://ide.c9.io/saijax/www
just whole authentication is so big that i can not put everything here...
EDIT:
here are some main files
passport.js
const GoogleStrategy = require("passport-google-oauth2")
.Strategy;
const mongoose = require("mongoose");
const keys = require("./keys");
module.exports = (passport) => {
passport.use(
new GoogleStrategy({
clientID: keys.googleClientID,
clientSecret: keys.googleClientSecret,
callbackURL: "/auth/google/callback",
proxy: true
}, (accessToken, refreshToken, profile, done) => {
const image = profile.photos[0].value.substring(0, profile.photos[0].value.indexOf("?"));
const newUser = {
googleID: profile.id,
email: profile.emails[0].value,
firstName: profile.name.givenName,
lastName: profile.name.familyName,
image: image
}
// CHECK FOR USER
User.findOne({
googleID: profile.id
}).then(user => {
if(user){
done(null, user);
} else {
// CREATE USER
new User(newUser)
.save()
.then(user => done(null,user));
}
})
})
);
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
User.findById(id)
.then(user => done(null, user));
});
}
auth.js
const express = require("express");
const passport = require("passport");
const router = express.Router();
router.get("/google", passport.authenticate("google", {
scope: [
"profile",
"email"
]
}));
router.get("/google/callback", passport.authenticate("google", {
failureRedirect: "/"
}), (req, res) => {
req.flash("success_msg", "Successfully Logged In");
res.redirect("/dashboard");
});
router.get("/verify", (req, res) => {
if(req.user){
console.log(req.user);
} else {
console.log("Not auth");
}
});
router.get('/logout', (req, res) => {
req.logout();
req.flash("success_msg", "Successfully Logged Out");
res.redirect('/');
});
module.exports = router;
app.js
// SETUP
const express = require("express");
const mongoose = require("mongoose");
const passport = require("passport");
const cookieParser = require("cookie-parser");
const session = require("express-session");
const exphbs = require("express-handlebars");
const bodyParser = require("body-parser");
const methodOverride = require("method-override");
const flash = require("connect-flash");
// LOAD GOOGLE AND MONGO KEYS
const keys = require("./config/keys");
// LOAD MODELS
require("./models/story");
require("./models/user");
// PASSPORT CONFIG
require("./config/passport")(passport);
// LOAD ROUTES
const auth = require("./routes/auth");
const index = require("./routes/index");
const stories = require("./routes/stories");
// HANLEBARS HELPERS
const {
truncate,
stripTags,
formatDate,
select,
editIcon
} = require("./helpers/hbs");
// MONGOOSE CONNECT
mongoose.connect(keys.mongoURI)
.then(() => {
console.log("MongoDB Connected...");
}).catch(err => console.log(err));
// USE APP
const app = express();
// CSS CONFIG
app.use(express.static(__dirname + "/public"));
// VIEW ENGINE
app.engine("handlebars", exphbs({
helpers: {
truncate: truncate,
stripTags: stripTags,
formatDate: formatDate,
select: select,
editIcon: editIcon
},
defaultLayout: "main"
}));
app.set("view engine", "handlebars");
// BODY PARSER
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
// METHOD OVERRIDE
app.use(methodOverride("_method"));
// FLASH
app.use(flash());
// COOKIE PARSER
app.use(cookieParser());
// SESSION MIDDLEWARE
app.use(session({
secret: "KAPPA",
resave: false,
saveUninitialized: false
}));
// PASSPORT MIDDLEWARE
app.use(passport.initialize());
app.use(passport.session());
// SET GLOBAL VARS
app.use((req, res, next) => {
res.locals.user = req.user || null;
res.locals.success_msg = req.flash("success_msg");
res.locals.error_msg = req.flash("error_msg");
next();
});
// ROUTES
app.use("/", index);
app.use("/auth", auth);
app.use("/stories", stories);
UPDATE: well, i dont know if it was silly mistake or not, but it seems like mobile can not read
callbackURL: "/auth/google/callback"
instead i changed following line with
callbackURL: keys.callback + "/auth/google/callback"
where keys.callback is url for my app(from c9/heroku) ... now it works perfectly!
I'm sure, I'm doing something wrong coz of my lack of experience with this technologies.
So here I'm trying to authenticate my user.
in server.js I have the following :
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
//var configDB = require('./config/database.js');
require('./config/environement.js')(app, express);
require('./config/routes.client.js')(app);
//setting all modules routes
require('./api/oAuth/routes.js')(app);
app.listen(port);
In environement.js :
module.exports = function(app, express) {
app.configure(function() {
var path = require('path');
var mongoose = require('mongoose');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
/* je pense que ce code n'a rien a faire ici*/
var User = require('./../models/user.js');
passport.use(new LocalStrategy(
function(username, password, done) {
User.findOne({
username: username
}, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false, {
message: 'Incorrect username.'
});
}
if (!user.validPassword(password)) {
return done(null, false, {
message: 'Incorrect password.'
});
}
return done(null, user);
});
}));
app.use(express.logger());
app.use(express.static(path.join(__dirname + '/../views')));
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.session({secret: 'm4B1teD4nsTaG0rgE'}));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
/*fin*/
mongoose.connect('mongodb://localhost/passport_local_mongoose');
app.set('views', __dirname + '/../views');
app.set('view engine', 'jade'); //extension of views
console.log("config ok");
});
//development configuration
app.configure('development', function() {
app.use(express.errorHandler({
dumpExceptions: true,
showStack: true
}));
});
//production configuration
app.configure('production', function() {
app.use(express.errorHandler());
});
};
And finaly my api/oAuth/routes.js
var User = require('../../models/user.js');
var passport = require('passport');
module.exports = function(app) {
app.get('/register', function(req, res) {
res.render('../api/oAuth/views/register.page.jade');
});
//Route vers /login en get et post
app.get('/login', function(req, res) {
res.render('../api/oAuth/views/login.page.jade');
});
app.post('/api/oAuth/login', function(req, res, next) {
console.log("post login = ok");
passport.authenticate('local',function(req, res) {
// If this function gets called, authentication was successful.
// `req.user` contains the authenticated user.
res.redirect('/users/' + req.user.username);
});
});
app.post('/api/oAuth/register', function(req, res) {
User.register(
new User({
username: req.body.username
}), req.body.password, function(err, user) {
if (err) {
res.send(err);
}
else {
res.send("Success");
}
});
});
}
Edit : Added user.js
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
passportLocalMongoose = require('passport-local-mongoose');
var passport = require('passport');
var User = new Schema({
username: String,
password: String
});
User.plugin(passportLocalMongoose);
passport.serializeUser(function(user, done) {
console.log("serializeUser");
done(null, user);
});
passport.deserializeUser(function(user, done) {
console.log("deserializeUser");
done(null, user);
});
module.exports = mongoose.model('User', User);
When the app goes into passport.authenticate() it does a lot of thing then it return to passport.authenticate() in a loop way. When I use the custom callback I realize that passport.authenticate() is going smoothly but the problem seems to be in req.logIn() function. I don't know what to do in order to make this work, and I tried a lot. I feel like a blind man trying to drive a car :D.