In my React web app, I have a button in
http://localhost:3000/login
pointed at the following address:
http://localhost:8000/api/auth/login/facebook
The API caught him, check user with passport then calls a callback like that:
app.get('/api/auth/login/facebook',
passport.authenticate('facebook', { scope: ['email'] }));
app.get('/api/auth/facebook/callback', passport.authenticate('facebook'),
(req, res) => {
console.log(req.user);
res.send('ok');
}
);
I configured passport like that:
const FacebookStrategy = require('passport-facebook').Strategy;
const GoogleStrategy = require('passport-google').Strategy;
const users = require('../models').users;
module.exports = (passport) => {
/*passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_APP_ID,
clientSecret: process.env.GOOGLE_APP_SECRET,
callbackURL: "https://hsoc.herokuapp.com/auth/login/google/return",
profileFields: ['profile','email'],
enableProof: true
},
(accessToken, refreshToken, profile, cb) => {
console.log("PROFILE: ");
console.log(util.inspect(profile, false, null));
users
.findOrCreate({where: {GOOGLE_ID: profile.id, EMAIL: profile.emails[0].value}})
.spread((user, created) => {
// console.log(user.get({
// plain: true
// }));
// console.log(created);
return cb(null, user);
});
}
));*/
passport.use(new FacebookStrategy({
clientID: "",
clientSecret: "",
authParameters: {
scope: "user_posts,manage_pages"
},
callbackURL: "http://localhost:8000/api/auth/facebook/callback",
profileFields: ['id', 'displayName', 'photos', 'email'],
enableProof: true
},
(accessToken, refreshToken, profile, cb) => {
console.log(profile._json);
return cb(null,'hei');
}
));
};
After login with facebook, how can I redirect the page on localhost:3000 not localhost:8000.
Related
im making a login for Discord but im getting a 302 code error
Here is the image my login code is:
app.get("/login", (req, res) => {
res.redirect(`https://discord.com/api/oauth2/authorize?client_id=${
process.env.bot_id
}&redirect_uri=${encodeURIComponent(
process.env.bot_redirect
)}&response_type=code&scope=${encodeURIComponent(
["identify", "guilds"].join(" ")
)}`)
});
app.get("/auth/callback", passport.authenticate("discord"), (req, res) => {})
bindAuth(app, client)
function bindAuth(app, client) {
app.use(session({store: new SQLiteStore(), secret: "ChatGlobalAPI", resave: false, saveUninitialized: false}))
passport.serializeUser(function(user, done) {
done(null, user);
})
passport.deserializeUser(function(obj, done) {
done(null, obj);
})
passport.use(
new Strategy(
{
clientID: process.env.bot_id,
clientSecret: process.env.bot_secret,
callbackURL: process.env.bot_redirect,
scope: ["identify", "guilds"]
},
function(accessToken, refreshToken, profile, done) {
process.nextTick(function() {
profile.tokens = { accessToken }
return done(null, profile)
})
}
)
)
}
This is the first time this happens, i tried to search in google and here, in stackoverflow but i dont get an answer, i tried all but nothing.
I'm trying to access the user's name, avatar, and what servers they're in, but I get a weird error.
Here's the code where I think it orginiated from:
const DiscordStrategy = require("passport-discord").Strategy;
const passport = require("passport");
passport.use(
new DiscordStrategy(
{
clientID: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
callbackURL: process.env.CLIENT_REDIRECT,
scope: ["identify", "guilds"],
},
(accessToken, refreshToken, profile, done) => {
done(null, {
discordId: profile.id,
username: profile.username,
guilds: profile.guilds,
});
}
)
);
If you need more then that just comment and I'll edit.
Here's the site https://pulsebot-dashboard.herokuapp.com/
I've built myself an express back-end API (Port 3000) and a Vue.js front end on port (8080) I've implemented a passport authentication login system on my back-end server. If i go to localhost:3000/auth/google the login system works and I get a google-ID in my mongoose database.
I have this code on my server which redirects to my front end on successful login, but how do i now know a user is logged in on my Vue.js front-end?
app.get(
'/auth/google',
passport.authenticate('google', {
scope: ['profile']
})
);
app.get(
'/auth/google/callback',
passport.authenticate('google', { failureRedirect: '/login' }),
function(req, res) {
res.redirect('http://localhost:8080/profile');
}
);
and my passport config is set up like so
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((id, done) => {
User.findById(id, function(err, user) {
done(err, user);
});
});
module.exports = function(passport, GoogleStrategy) {
passport.use(
new GoogleStrategy(
{
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: 'http://localhost:3000/auth/google/callback'
},
function(token, tokenSecret, profile, done) {
var query = { googleId: profile.id };
var update = {
$set: {
googleId: profile.id
}
};
var options = { new: true, upsert: true };
User.findOneAndUpdate(query, update, options, function(err, u) {
return done(err, u);
});
}
)
);
};````
You can generate a jsonwebtoken and set it in the cookie of the response object
app.get(
'/auth/google/callback',
passport.authenticate('google', { failureRedirect: '/login' }),
function(req, res) {
let token = jwt.sign({
exp: Math.floor(Date.now() / 1000) + (60 * 60),
user: req.user //if you have user here
}, 'secret');
res.cookie("token", token, {httpOnly:false})
res.redirect('http://localhost:8080/profile');
}
);
and in Vue you can use a package like vue-cookies to get the cookie $cookies.get('token')
Inside your protected route, you should be able to see the User in the req.user field:
app.get('/protectedURL',
passport.authenticate('google'),
function(req, res) {
res.json(req.user);
});
The call to /protectedURL will return a 401 error if the user is not logged in.
For my application(Node.js) i'm using passport-facebook and everything works well except that i can't get user email. I found a lot of issues on this subject but for some reason they not fix my problem. I would be really preciate for some help. So my configurations:
app.js
app.get('/auth/facebook', passport.authenticate('facebook', {scope: 'email'}));
// in scope i tried a different options like ['email'] or ['emails'] and so go on
app.get('/auth/facebook/callback',
passport.authenticate('facebook', {
successRedirect: '/',
failureRedirect: '/login'
}));
passport.js:
passport.use('facebook', new FacebookStrategy({
clientID : secret.facebook.clientID,
clientSecret : secret.facebook.clientSecret,
callbackURL : secret.facebook.callback
},
function(access_token, refreshToken, profile, done) {
console.log(profile) // here i got all profile data except email
process.nextTick(function() {
User.findOne({ 'facebook.id' : profile.id }, function(err, user) {
if (err)
return done(err);
if (user) {
return done(null, user);
} else {
var newUser = new User();
console.log(profile.email) // here i got undefined
newUser.facebook.id = profile.id;
newUser.facebook.token = access_token;
newUser.facebook.firstName = profile.name.givenName;
newUser.facebook.lastName = profile.name.familyName;
newUser.facebook.email = profile.email;
newUser.save((err) => {
if (err)
throw err;
return done(null, newUser);
});
}
});
});
}));
facebook-secret.js
module.exports = {
facebook: {
clientID: '****',
clientSecret: '********',
callback: '/auth/facebook/callback',
profileFields: ['id', 'email']
}
}
in UserSchema:
facebook: {
id: String,
token: String,
email: String,
name: String,
}
facebok - settings
graph - api
in passport.js :
passport.use('facebook', new FacebookStrategy({
clientID : secret.facebook.clientID,
clientSecret : secret.facebook.clientSecret,
callbackURL : secret.facebook.callback
},
change to:
passport.use('facebook', new FacebookStrategy({
clientID : secret.facebook.clientID,
clientSecret : secret.facebook.clientSecret,
callbackURL : secret.facebook.callback,
profileFields : secret.facebook.profileFields
},
My profileField : profileFields: ['id', 'displayName', 'email', 'first_name', 'middle_name', 'last_name']
Try to pass the scopes in url as param like you used in graph API(?fields=id,email...).
I know variations of this questions have been asked multiple times. My understanding is that you basically have to watch your if/else logic and make sure that done isn't being called multiple times.
Twitter and Google work fine. Facebook is giving me this error though:
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
at ServerResponse.header (/Users/azerner/code/mean-starter/node_modules/express/lib/response.js:718:10)
at ServerResponse.location (/Users/azerner/code/mean-starter/node_modules/express/lib/response.js:835:8)
at ServerResponse.redirect (/Users/azerner/code/mean-starter/node_modules/express/lib/response.js:874:8)
at complete (/Users/azerner/code/mean-starter/node_modules/passport/lib/middleware/authenticate.js:241:26)
at /Users/azerner/code/mean-starter/node_modules/passport/lib/middleware/authenticate.js:250:15
at pass (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:427:14)
at Authenticator.transformAuthInfo (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:449:5)
at /Users/azerner/code/mean-starter/node_modules/passport/lib/middleware/authenticate.js:247:22
at /Users/azerner/code/mean-starter/node_modules/passport/lib/http/request.js:51:7
at pass (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:273:43)
at serialized (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:282:7)
at /Users/azerner/code/mean-starter/server/passport.js:17:5
at pass (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:290:9)
at Authenticator.serializeUser (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:295:5)
at IncomingMessage.req.login.req.logIn (/Users/azerner/code/mean-starter/node_modules/passport/lib/http/request.js:48:29)
passport.js
var LocalStrategy = require('passport-local').Strategy;
var FacebookStrategy = require('passport-facebook').Strategy;
var TwitterStrategy = require('passport-twitter').Strategy;
var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
var mongoose = require('mongoose');
var User = mongoose.model('User');
var Local = mongoose.model('Local');
var Facebook = mongoose.model('Facebook');
var Twitter = mongoose.model('Twitter');
var Google = mongoose.model('Google');
var bcrypt = require('bcrypt');
var config = require('./config.json');
module.exports = function(passport) {
passport.serializeUser(function(user, done) {
done(null, user._id);
});
passport.deserializeUser(function(id, done) {
User
.findById(id).populate('local').exec()
.then(function(user) {
console.log('deserializeUser found user: ', user);
done(null, user);
}, done)
;
});
// LOCAL
passport.use(new LocalStrategy(function(username, password, done) {
Local
.findOne({ username: username })
.select('username role hashedPassword')
.exec()
.then(function(local) {
if (!local) {
return done(null, false);
}
var validPassword = bcrypt.compareSync(password, local.hashedPassword);
if (!validPassword) {
return done(null, false);
}
else {
User
.findOne({ local: local })
.populate('local')
.exec()
.then(function(user) {
return done(null, user);
})
;
}
})
;
}));
// FACEBOOK
passport.use(new FacebookStrategy({
clientID: config.facebookAuth.clientID,
clientSecret: config.facebookAuth.clientSecret,
callbackURL: config.facebookAuth.callbackURL
}, function(token, refreshToken, profile, done) {
// asynchronous
process.nextTick(function() {
Facebook
.findOne({ id: profile.id })
.select('id token')
.exec()
.then(function(facebook) {
if (facebook) {
User
.findOne({ facebook: facebook._id }).exec()
.then(function(user) {
return done(null, user);
})
;
}
else {
Facebook
.create({ id: profile.id, token: token })
.then(function(createdFacebook) {
User
.create({ facebook: createdFacebook })
.then(function(user) {
return done(null, user);
})
;
})
;
}
})
.then(function(err) {
return done(err);
})
;
});
}));
// TWITTER
passport.use(new TwitterStrategy({
consumerKey: config.twitterAuth.consumerKey,
consumerSecret: config.twitterAuth.consumerSecret,
callbackURL: config.twitterAuth.callbackURL
}, function(token, tokenSecret, profile, done) {
process.nextTick(function() {
Twitter
.findOne({ id: profile.id })
.select('id token')
.exec()
.then(function(twitter) {
if (twitter) {
User
.findOne({ twitter: twitter._id }).exec()
.then(function(user) {
return done(null, user);
})
;
}
else {
Twitter
.create({ id: profile.id, token: token })
.then(function(createdTwitter) {
User
.create({ twitter: createdTwitter })
.then(function(user) {
return done(null, user);
})
;
})
;
}
})
.then(null, function(err) {
return done(err);
})
;
});
}));
// GOOGLE
passport.use(new GoogleStrategy({
clientID: config.googleAuth.clientID,
clientSecret: config.googleAuth.clientSecret,
callbackURL: config.googleAuth.callbackURL
}, function(token, refreshToken, profile, done) {
process.nextTick(function() {
Google
.findOne({ id: profile.id })
.select('id token')
.exec()
.then(function(google) {
if (google) {
User
.findOne({ google: google._id }).exec()
.then(function(user) {
return done(null, user);
})
;
}
else {
Google
.create({ id: profile.id, token: token })
.then(function(createdGoogle) {
User
.create({ google: createdGoogle })
.then(function(user) {
return done(null, user);
})
;
})
;
}
})
.then(null, function(err) {
return done(err);
})
;
});
}));
};
auth.routes.js
var mongoose = require('mongoose');
var express = require('express');
var passport = require('passport');
var Auth = require('./auth.service.js');
try {
var User = mongoose.model('User');
}
catch(e) {
var User = mongoose.model('User', require('../users/user.model.js').UserSchema);
}
var router = express.Router();
// LOCAL
router.post('/login', passport.authenticate('local'), function(req, res) {
res.status(200).json(req.user);
});
router.get('/logout', Auth.isLoggedIn, function(req, res) {
req.logout();
res.status(204).end();
});
router.get('/current-user', Auth.isLoggedIn, function(req, res) {
res.status(200).json(req.user);
});
// FACEBOOK
router.get('/auth/facebook', passport.authenticate('facebook'));
router.get('/auth/facebook/callback',
passport.authenticate('facebook', {
successRedirect: '/',
failureRedirect: '/login'
})
);
// TWITTER
router.get('/auth/twitter', passport.authenticate('twitter'));
router.get('/auth/twitter/callback',
passport.authenticate('twitter', {
successRedirect: '/',
failureRedirect: '/login'
})
);
// GOOGLE
router.get('/auth/google', passport.authenticate('google', { scope: ['profile'] }));
router.get('/auth/google/callback',
passport.authenticate('google', {
successRedirect: '/',
failureRedirect: '/login'
})
);
module.exports = router;
It's also worth noting that I have been using this to block Facebook, but I unblocked it to work on this. I did the commands, force quit Chrome and reopened it, and now I can log into facebook.com fine.
Edit: Oh, and I checked MongoHub and it shows that the User (and Facebook subdocument) have been created.