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.
Related
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.
I'm working with nodejs+express+mongo and angularjs(MEAN). I'm login in with Facebook strategy for passport but I can't seem to find the way to access the user info(req.user) from my angular client.
It should be noted that the angular front is on another app and web server, apart from the node express mongo side.
This is my nodejs code:
passport.serializeUser(function(user, done){
done(null, user._id);
});
passport.deserializeUser(function(id, done){
UserModel.findById(id, function(err, user){
done(err, user);
});
});
passport.use(new FacebookStrategy({
clientID: config.facebook.appId,
clientSecret: config.facebook.appSecret,
callbackURL: config.facebook.redirectUri,
scope: config.facebook.scope,
profileFields: ['name','displayName','gender','profileUrl','email']
},
function(accessToken, refreshToken, profile, done) {
UserModel.findOne( {$or:[{'facebook_profile.id': profile.id},{'email':profile.emails[0].value}]}, function(err, user){
var newuser = new UserModel();
if(err){
return done(err);
}
if(user){
return done(null, user);
}
else {
newuser.facebook_profile.id = profile.id;
newuser.facebook_profile.name = profile.displayName
return done(null, newuser);
}
});
})
);
app.get('/auth/is_auth', function(req, res){
if (req.isAuthenticated()){
res.json(req.user);
}
})
After this, from Postman I call
http://localhost:3000/auth/is_auth
But req.isAuthenticated() is always FALSE
What can it be, I can't never get the user info
req.isAuthenticated() is false, if you use CORS and in your ajax request you didn't set withCredentials to true. Be sure withCredentials is set to true.
I saw this very nice article from Scotch.io:
https://scotch.io/tutorials/easy-node-authentication-linking-all-accounts-together
It is from January 2014, so it's getting a bit old :) but Chris shows us how we might check the value of req.user inside the passport.authenticate('linkedin') callback, like so:
passport.use(new LinkedInStrategy({
consumerKey: linkedinConfig.clientId,
consumerSecret: linkedinConfig.clientSecret,
callbackURL: serverBaseUrl + '/auth/linkedin/callback'
},
function (req, token, tokenSecret, profile, done) {
if (req.user) {
var user = req.user;
user.linkedin.id = profile.id;
user.linkedin.token = token;
user.save(function (err) {
if (err) {
done(err);
}
else {
done(null, user);
}
});
}
else{
User.findOne({'linkedin.id': profile.id}, function (err, user) {
if (err) {
done(err);
}
else if (user) {
done(null, user);
}
else {
done(null, null);
}
});
}
}
));
my question is - how did Chris get the req value passed to this callback?
in other words the callback signature is supposed to be this:
function (token, tokenSecret, profile, done)
not this
function (req, token, tokenSecret, profile, done)
...now passport appears to be standard Express middleware, with the signature of
module.exports = function(req,res,next){};
but I don't see how to access the req variable with Passport the way Chris does. Am I missing something from his article somehow?
Looking at tutorial , try this :
passport.use(new LinkedInStrategy({
consumerKey: linkedinConfig.clientId,
consumerSecret: linkedinConfig.clientSecret,
callbackURL: serverBaseUrl + '/auth/linkedin/callback',
passReqToCallback : true
}
LinkedIn strategy inherits from Oauth1 strategy in this line explains how works , this should be sufficient. hope it helps.
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.
I am using passportjs for facebook authentication. Here is my facebook strategy:
passport.use(new FacebookStrategy({
clientID: config.facebook.clientID,
clientSecret: config.facebook.clientSecret,
callbackURL: config.facebook.callbackURL
}, function(accessToken, refreshToken, profile, done) {
User.findOne({ 'facebook.id': profile.id }, function (err, user) {
if (err) { return done(err); }
if (!user) {
user = new User({
name: profile.displayName,
email: profile.emails[0].value,
username: profile.username,
provider: 'facebook',
facebook: profile._json
});
user.save(function (err) {
if (err) {
console.log(err);
}
return done(err, user);
});
} else {
return done(err, user);
}
});
}));
I added the following routes:
app.get('/facebook/auth', passport.authenticate('facebook', { scope: [ 'email', 'user_about_me', 'publish_actions']}), function(req, res) { });
// I need the following fix due to this: http://stackoverflow.com/a/17015836/289246
app.get('/facebook/auth/callback', function(req, res, next) {
if (req.query && !req.query.error && req.query.error_code) {
req.query.error = true;
}
next();
},
passport.authenticate('facebook', { failureRedirect: '/facebook-auth-failure', successRedirect: '/auth-success', failureFlash: true })
);
app.get('/facebook-auth-failure', users.authFailure);
app.get('/auth-success', users.authSuccess);
My users.authFailure method is:
exports.authFailure = function (req, res) {
var error = ???
// How can I get here the error message??
res.render('auth-failure', {
error: error || 'An error has accured'
});
};
In case of facebook authentication failure, how can I get the error message (I want to display it to the user)?
Since you're using failureFlash, this should do it:
var error = req.flash('error');
I experienced many many problems and bugs and configurations issues during working with Passport. My solution was to move to Everyauth.
I don't know if this will be any use to you but I got access to flash messages this way.
When you are defining the FacebookStrategy use the passReqToCallback parameter.
passport.use(new FacebookStrategy({
clientID: facebook.getClientID(),
clientSecret: facebook.getClientSecret(),
callbackURL: facebook.getCallback(),
passReqToCallback: true
this will allow you to add the req.flash() as a parameter to the done() like so
return done(false, user, reg.flash('success', 'Sign in successfull'));
Hope that sheds some light on the situation for you or anybody else looking for help