Been having some trouble for the past week getting this link to work. Feel like I'm misunderstanding something from the flow.
What I'm struggling with was implementing the passport with passport-facebook. I want to include the passport.authenticate inside the same route as the account linking. Currently only managed to separate the two processes and having two logins. Looking to merge them.
As can be seen here http://recordit.co/osdMl0MUCL
Is there no way to do the passport.authenticate inside the link route ? Been trying with no success.
Tried to move the passport.authenticate inside app.get('/authorize but don't know how to handle the const redirectURISuccess = ${redirectURI}&authorization_code=${authCode};
res.redirect(redirectURISuccess);
I'm thinking would need to do this inside the app.get(/auth/fb/callback' ... but not sure how.
This is what I have currently
'use strict';
require('dotenv').config();
const express = require('express');
const router = express.Router();
const bodyParser = require('body-parser');
const http = require('http');
const port = '3000';
const passport = require('passport');
const FacebookStrategy = require('passport-facebook').Strategy;
const fbConfig = require('./oauth');
const cookieParser = require('cookie-parser');
const session = require('express-session');
// used to serialize the user for the session
// Not using these yet
passport.serializeUser(function (user, done) {
done(null, user.id);
});
passport.deserializeUser(function (obj, done) {
done(null, obj);
});
const Botly = require('botly');
const botly = new Botly({
accessToken: process.env.ACCESS_TOKEN,
verifyToken: '123123321' // the verification token you provided when defining the webhook in facebook
});
const app = express();
// Listen on the account link event
botly.on('account_link', (sender, message, link) => {
// Continue conversation
console.log('CONFIRMED AUITH', link);
botly.sendText({
id: sender,
text: (link.status === 'unlinked') ? 'sorry to see you go' : 'Welcome'
});
botly.sendButtons({
id: sender,
text: 'Please Login Again :-) This time for real',
buttons: [ botly.createAccountLinkButton(`https://${process.env.LOGIN_DOMAIN}/auth/fb/?senderId=' + sender/`) ]
});
});
botly.on('message', (senderId, message, data) => {
const text = `echo: ${data.text}`;
botly.sendText({
id: senderId,
text: text
});
botly.sendButtons({
id: senderId,
text: 'Please Login :)',
buttons: [ botly.createAccountLinkButton(`https://${process.env.LOGIN_DOMAIN}/authorize/`), botly.createAccountUnLinkButton() ]
});
});
app.use(bodyParser.json());
app.use('/', router);
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(session({ secret: 'its_my_secret', resave: true, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.use('/webhook', botly.router());
app.set('port', port);
/*
* This path is used for account linking. The account linking call-to-action
* (sendAccountLinking) is pointed to this URL.
*
*/
app.get('/authorize', function (req, res) {
// Passport setup
passport.use('facebook', new FacebookStrategy({
clientID: fbConfig.facebook.clientID,
clientSecret: fbConfig.facebook.clientSecret,
callbackURL: fbConfig.facebook.callbackURL,
profileFields: [ 'id', 'displayName', 'email' ]
},
// facebook will send back the tokens and profile
function (request, access_token, refresh_token, profile, done) {
// asynchronous
process.nextTick(function () {
console.log('WATCH THIS: ', profile);
return done(null, profile);
});
}));
console.log('%%%%%%%% AccountLinking Testing');
const accountLinkingToken = req.query.account_linking_token;
const redirectURI = req.query.redirect_uri;
console.log('%%%%%%%% /authorize called with accountLinkingToken %s, redirectURI %s', accountLinkingToken, redirectURI);
// Authorization Code should be generated per user by the developer. This will
// be passed to the Account Linking callback.
const authCode = '1234567890';
// Redirect users to this URI on successful login
const redirectURISuccess = `${redirectURI}&authorization_code=${authCode}`;
res.redirect(redirectURISuccess);
});
app.get('/auth/fb', (req, res, next) => {
req.session.senderId = req.query.senderId;
passport.authenticate('facebook', { scope: [ 'email' ] },
{
state: {
senderId: req.query.senderId // senderId will be used after auth to reply to the user
}
})(req, res, next);
});
// Redirection after login
app.get('/auth/fb/callback',
passport.authenticate('facebook', {
successRedirect: `https://m.me/${process.env.app_name}`, // The webview I want to open if user logs in
failureRedirect: '/somePage' // redirect to Messenger if failure
}));
const server = http.createServer(app);
server.listen(port);
I solved it I think. Probably not the best way to go about it though. I'm passing the account linked redirect URI to the callback route and resolving the passport.authenticate in there redirecting if needed.
'use strict';
require('dotenv').config();
const express = require('express');
const router = express.Router();
const bodyParser = require('body-parser');
const LINKED = {};
const http = require('http');
const port = '3000';
const passport = require('passport');
const FacebookStrategy = require('passport-facebook').Strategy;
const fbConfig = require('./oauth');
const cookieParser = require('cookie-parser');
const session = require('express-session');
// used to serialize the user for the session
// Not using these yet
passport.serializeUser(function (user, done) {
done(null, user.id);
});
passport.deserializeUser(function (obj, done) {
done(null, obj);
});
const Botly = require('botly');
const botly = new Botly({
accessToken: process.env.ACCESS_TOKEN,
verifyToken: '123123321' // the verification token you provided when defining the webhook in facebook
});
const app = express();
// Listen on the account link event
botly.on('account_link', (sender, message, link) => {
// Continue conversation
console.log('CONFIRMED AUITH', link);
botly.sendText({
id: sender,
text: (link.status === 'unlinked') ? 'sorry to see you go' : 'Welcome'
});
});
botly.on('message', (senderId, message, data) => {
const text = `echo: ${data.text}`;
botly.sendText({
id: senderId,
text: text
});
botly.sendButtons({
id: senderId,
text: 'Please Login :)',
buttons: [ botly.createAccountLinkButton(`https://${process.env.LOGIN_DOMAIN}/authorize/?senderId=' + senderId/`), botly.createAccountUnLinkButton() ]
});
});
app.use(bodyParser.json());
app.use('/', router);
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(session({ secret: 'its_my_secret', resave: true, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.use('/webhook', botly.router());
app.set('port', port);
// Passport setup
passport.use('facebook', new FacebookStrategy({
clientID: fbConfig.facebook.clientID,
clientSecret: fbConfig.facebook.clientSecret,
callbackURL: fbConfig.facebook.callbackURL,
profileFields: [ 'id', 'displayName', 'email' ]
},
// facebook will send back the tokens and profile
function (request, access_token, refresh_token, profile, done) {
// asynchronous
process.nextTick(function () {
return done(null, profile);
});
}));
/*
* This path is used for account linking. The account linking call-to-action
* (sendAccountLinking) is pointed to this URL.
*
*/
app.get('/authorize', function (req, res, next) {
req.session.senderId = req.query.senderId;
console.log('%%%%%%%% AccountLinking Testing');
const accountLinkingToken = req.query.account_linking_token;
const redirectURI = req.query.redirect_uri;
console.log('%%%%% /authorize called with accountLinkingToken %s, redirectURI %s', accountLinkingToken, redirectURI);
// Authorization Code should be generated per user by the developer. This will
// be passed to the Account Linking callback.
const authCode = '1234567890';
// Redirect users to this URI on successful login
const redirectURISuccess = `${redirectURI}&authorization_code=${authCode}`;
LINKED.redirect = redirectURISuccess;
console.log('redirect to this ', redirectURISuccess);
passport.authenticate('facebook', { scope: [ 'email' ] },
{
state: {
senderId: req.query.senderId // senderId will be used after auth to reply to the user
}
})(req, res, next);
});
// Redirection after login
app.get('/auth/fb/callback', (req, res, next) => {
passport.authenticate('facebook', (err, user, info) => {
if (err) { return next(err); }
if (!user) {
console.log('bad', info);
return res.redirect(LINKED.redirect);
}
console.log('good');
LINKED.user = user;
})(req, res, next);
res.redirect(LINKED.redirect);
});
const server = http.createServer(app);
server.listen(port);
Related
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
I have a React client setup at localhost:3000 and a node.js server at localhost:5000
I'm trying a simple auth flow in which the client tries to authenticate with the server using Passport.js Google OAuth2.0 and staying authenticated using express-sessions with a MongoDB store.
I believe the reason I'm finding req.user is undefined is because of my lack of understanding of how the auth flow is supposed to work versus any issues with the actual code.
I'm initiating the auth flow through the following code in the react client:
<Button href="http://localhost:5000/auth/google">
Login using Google
</Button>
The following is my auth.js file:
const express = require("express");
const passport = require("passport");
const router = express.Router();
// #desc Auth with Google
// #route GET /auth/google
router.get("/google", passport.authenticate("google", { scope: ["profile"] }));
// #desc Google auth callback
// #route GET /auth/google/callback
router.get(
"/google/callback",
passport.authenticate("google", {
failureRedirect: "/",
successRedirect: "http://localhost:3000/dashboard",
})
);
// #desc Logout user
// #route /auth/logout
router.get("/logout", (req, res) => {
req.logout();
res.redirect("/");
});
module.exports = router;
The following is my Google Strategy configuration:
const GoogleStrategy = require("passport-google-oauth20").Strategy;
const mongoose = require("mongoose");
const User = require("../models/User");
module.exports = function (passport) {
passport.use(
new GoogleStrategy(
{
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: "http://localhost:5000/auth/google/callback",
},
async (accessToken, refreshToken, profile, done) => {
const newUser = {
googleId: profile.id,
displayName: profile.displayName,
firstName: profile.name.givenName,
lastName: profile.name.familyName,
image: profile.photos[0].value,
};
try {
let user = await User.findOne({ googleId: profile.id });
if (user) {
done(null, user);
} else {
user = await User.create(newUser);
done(null, user);
}
} catch (err) {
console.error(err);
}
}
)
);
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
User.findById(id, (err, user) => done(err, user));
});
};
The following code is my index.js which brings everything together:
const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const connectDB = require("./config/db");
const morgan = require("morgan");
const passport = require("passport");
const session = require("express-session");
const MongoStore = require("connect-mongo")(session);
// Dotenv config
const dotenv = require("dotenv").config({
path: "./config/config.env",
});
// Passport config
require("./config/passport")(passport);
// MongoDB config
connectDB();
const app = express();
const PORT = process.env.PORT;
// Middleware
app.use(cors());
app.use(bodyParser.json());
app.use(morgan("dev"));
// Sessions
app.use(
session({
secret: "stackoverflow",
resave: false,
saveUninitialized: false,
store: new MongoStore({ mongooseConnection: mongoose.connection }),
})
);
// Passport middleware
app.use(passport.initialize());
app.use(passport.session());
app.use("/posts", require("./routes/posts"));
app.use("/auth", require("./routes/auth"));
app.listen(PORT, () => console.log(`Server listening # port ${PORT}`));
I am fetching posts from the DB through one of the routes after user login:
...
// #desc Get all posts
// #route GET /posts
router.get("/", (req, res) => {
const posts = Post.find(function (error, posts) {
if (error) return console.error(error);
console.log(req.user) // <------ is undefined
res.json(posts);
});
});
I'm assuming that after the user is being redirected to the dashboard and then sending a request to the route to get all posts, the user is not authenticated? Although I redirected the user towards this route after authenticating him?
The goal is definitely not to fetch the user at the /posts route but create a separate /user route that returns the user to the client, but that also results in req.user being undefined.
Finally got it to work.
I had to edit two things,
First (Server Side):
I had to setup CORS to allow cookies to pass through as such:
app.use(
cors({
origin: "http://localhost:3000", // allow to server to accept request from different origin
methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
credentials: true, // allow session cookie from browser to pass through
})
);
Second (Client Side):
I had to let Axios know that it has to send the cookie alongside the request as such:
axios
.get("http://localhost:5000/auth/user", { withCredentials: true })
.then(console.log)
.catch(console.error);
where the /auth/user route is defined as such:
router.get("/user", (req, res) => {
if (req.user) {
res.json(req.user);
}
});
These mistakes could have been avoided had I had a better understanding of the entire authentication process, of which now I do.
We live and we learn.
At first haidousm's answer did not work for me, what I did was I added { withCredentials: true } to the post request for my login as well.
Thats my code:
server.js:
require('dotenv').config()
var fs = require('fs')
var express = require('express')
var app = express()
var helmet = require('helmet')
var router = require('./router')
var session = require('express-session')
var passport = require('passport')
var cookie = require('cookie-parser')
var redis = require('redis').createClient(process.env.REDIS_PORT)
var redisStore = require('connect-redis')(session)
app.use(helmet())
app.use(cookie())
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
app.use(passport.initialize())
app.use(passport.session())
app.use(session({
store: new redisStore({client: redis}),
secret: 'rior124jybtyokipoev5432rtoe34wpta',
cookie: {
path: '/',
httpOnly: true,
maxAge: 1000*60*60*24*365,
secure: false
},
resave: false,
saveUninitialized: false
}))
app.use(router)
require('./config/passport');
app.listen(process.env._PORT, () => {
console.log('[Info][Backend] Backend http serve succesfuly started! Port: '+process.env._PORT);
})
router/index.js:
var router = require('express').Router()
var auth = require('../lib/auth_mw')
var fs = require('fs')
router.use(require('./logging'))
router.use(require('./news'))
router.get('/', (req, res) => {
res.contentType('text/plain')
res.end(fs.readFileSync(__dirname+'/../siteinfo.txt'))
})
router.get('/private', auth, (req, res) => {
res.end('private')
})
module.exports = router
config/passport.js:
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
var users = require('../models').users
passport.serializeUser(function(user, done) {
console.log('serialize: ', user);
done(null, user.email);
});
passport.deserializeUser(function(email, done) {
console.log('deserialize: ', email);
users.findOne({
attributes: [
'email'
],
where: {
email
}
}).then(user => {
done(null, user.email === email ? user.dataValues : false);
})
});
passport.use('local',
new LocalStrategy({ usernameField: 'email' }, async function(
email,
password,
done
) {
let user = await users.findOne({
attributes: [
'email',
'password'
],
where: {
email,
password
}
})
if (user.dataValues.email) {
return done(null, user.dataValues);
} else {
return done(null, false);
}
})
);
Login always succesfull, but when i'm trying to go to /private, deserialize function doesn't called! I found many resolves on the net, but doesn't help. Please, suggest as many resolves as you know
P.S. I use sequelize as a database driver (idk maybe it's important)
This query will return the correct user, So You don't need to check the output again.
users.findOne({
attributes: [
'email'
],
where: {
email
}
})
Try done(null, user.dataValues); instead of done(null, user.email === email ? user.dataValues : false);
I have this simple enough express application which tries to use Active Directory to authenticate the user. Here is my setup:
const express = require('express');
const session = require('express-session');
const passport = require('passport');
const ActiveDirectoryStrategy = require('passport-activedirectory');
const PORT = process.env.PORT || 8080;
// AD configuration. Real values omitted.
const config = {
url: 'ldaps://...',
baseDN: '...',
username: '...',
password: '...'
};
const app = express();
app.use(session({
secret: 'mysessionsecret',
resave: true,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
passport.use('ad', new ActiveDirectoryStrategy(
{
ldap: config
},
(profile, ad, done) => {
// The problem is here! This never gets called!
console.log('ActiveDirectoryStrategy activated.');
done('ActiveDirectoryStrategy not implemented.');
}
));
// route middleware to ensure user is logged in
const isLoggedIn = (req, res, next) =>
req.isAuthenticated() ? next() : res.redirect('/auth');
app.get('/', isLoggedIn, (req, res) => {
res.end('You are logged in.');
});
app.get('/unsecured', (req, res) => {
res.end('You are not logged in.');
});
app.get('/auth', passport.authenticate('ad', {
successRedirect: '/',
failureRedirect: '/unsecured'
}));
app.listen(PORT);
console.log('Listening on port ' + PORT);
However, the verifier function I pass for the constructor ActiveDirectoryStrategy never gets called. (This is the function with the signature (profile, ad, done)).
I am sure that there is no problem with the LDAP configuration, because I can access the active directory just fine with activedirectory module with the same parameters:
const ActiveDirectory = require('activedirectory');
const ad = new ActiveDirectory(config);
ad.findUser('username', (err, user) => {
if (err) {
return console.log(err);
}
console.log(JSON.stringify(user));
// prints an object with user's info
});
So there must be a problem with my routing. What am I doing wrong? Why is my verifier function not getting called?
The problem was a misconception I had. I thought the Passport.js's authenticate middleware would perform the NTLM handshake for me. This is not the case. passport-activedirectory actually needs something like IISNode to run in front of it in order to perform the NTLM handshake. Since the request does not contain the authentication information,
I settled on using express-ntlm middleware as a result. express-ntlm gives you the UserName, DomainName, and Workstation properties you can use. But if you want to acquire the full AD profile for some reason, you could setup a custom passport strategy like so:
const ActiveDirectory = require('activedirectory');
const CustomStrategy = require('passport-custom');
passport.use('ntlm-ad-backend', new CustomStrategy((req, done) => {
let username = req.ntlm.UserName;
AD.findUser(username, (err, profile) => {
if (err) {
console.log(err);
done(err);
}
if (!profile) {
done(new Error(`User ${req.ntlm.UserName} not found in Active Director.`));
} else {
done(null, profile);
}
});
}));
And then,
app.get('/auth', passport.authenticate('ntlm-ad-backend', {
successRedirect: '/',
failureRedirect: '/unsecured'
}));
Note that you will also have to implement serializeUser and deserializeUser.
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!