failed to retrieve accessToken from instagram with passportJS - passport.js

I am setting up my website with Passport-Instagram and I continue getting an error: "InternalOAuthError: Failed to obtain access token". I am simply trying to console.log my accessToken and my profile info when I try logging in but no matter which block of code I use whether it is jaredhansons GitHub for passport-instagram, I can not seem to obtain the access Token.
The first time that I used these setups it did actually redirect me to the Instagram login page but after the first time on a browser it just sends me this failed to obtain access token error.
I have tried using jared hanson's setup https://github.com/jaredhanson/passport-instagram/blob/master/examples/login/app.js
I have tried using https://medium.com/crowdbotics/add-instagram-login-to-your-nodejs-app-using-passportjs-be7e8e31efb8
//passport.js file
passport.use(new InstagramStrategy({
clientID: keys.instagramClientID,
clientSecret: keys.instagramClientSecret,
callbackURL: '/auth/instagram/callback',
proxy: true
}, (accessToken, refreshToken, profile, done) => {
console.log(accessToken);
console.log(profile);
//User.findOrCreate({ instagramId: profile.id }, function (err, user) {
return done(err, user);
//});
}
));
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
User.findById(id)
.then(user => done(null, user));
});
//auth.js file
router.get('/instagram', passport.authenticate('instagram'))
router.get('/instagram/callback',
passport.authenticate('instagram', { failureRedirect: '/' }),(req, res) => {
res.redirect('/dashboard');
});
I expect to console.log the accessToken given by Instagram.
GitHub repo: https://github.com/ValverdeDaniel/BRv2

Related

How would I redirect after authenticating a user using passportjs?

I looked in several posts, but I cannot find something that meets my situation.
To login (or signup) with google, you have to go to mydomain.com/login/google
You then, well, login with google, and then the callback is handled on mydomain.com/auth/google
Here is the code responsible for this.
app.get('/login/google', passport.authenticate('google'));
app.get('/auth/google',
passport.authenticate('google', { failureRedirect: '/login', failureMessage: false, session: false, failureFlash: true }),
function(req, res) {
res.redirect('/');
});
Here is where I store the users:
passport.use(new GoogleStrategy({
clientID: no,
clientSecret: definitely not,
callbackURL: 'https://no cuz privacy/auth/google'
},
async function(issuer, profile, cb) {
var user = await User.find({ google: true, googleid: profile.id })
if (!user[0]) {
// The Google account has not logged in to this app before. Create a
// new user record and link it to the Google account.
const newUser = await new User({ username: generateUsername(), google: true, googleid: profile.id, googleProfile: profile })
await newUser.save()
return cb(null, newUser);
} else {
// The Google account has previously logged in to the app. Get the
// user record linked to the Google account and log the user in.
console.log('exists')
return cb(null, newUser);
}
}
));
I think you have to do something with the callback function (cb()) to somehow go to app.get('/auth/google') for the redirect, but, all it does is print either exists or new in the console, spinning forever on the client side. Not sure how to redirect after the code determines either account exists or new account.
Edit: I just want to point out that the cb() function could also be done() too. For example:
function(accessToken, refreshToken, profile, done){
console.log("strategy");
console.log(profile);
console.log(accessToken);
console.log(refreshToken);
done(null, profile);
}
^^ Not my code --> PassportJS in Nodejs never call the callback function ^^

PassportJS Google oauth2.0 login/register

I've been trying to get the google oauth login system to work on multiple ports and found issues of saving the data (from backend to frontend) when redirecting (most tutorials do this on the same port which got me confused). I understand how to get data from backend on frontend (through axios) but am confused how to send data from backend to frontend, and so I found this tutorial similar to what I'm looking for. (I tried to adapt this to use google oauth instead of twitter)
However, in this tutorial during the google redirect, I'm getting an error:
Error: Failed to serialize user into session
On googling, most say it's related to the serializeUser and deserializeUser functions (which I however have). So I'm quite hard-stuck and am hoping to find a fix.
Here's my code:
passport.serializeUser((user, done) => {
done(null, user.id);
});
// deserialize the cookieUserId to user in the database
passport.deserializeUser((id, done) => {
User.findById(id)
.then(user => {
done(null, user);
})
.catch(e => {
done(new Error("Failed to deserialize an user"));
});
});
passport.use(
new GoogleStrategy(
{
clientID: keys.googleClientID,
clientSecret: keys.googleSecret,
callbackURL: "http://localhost:5000/auth/google/redirect"
},
(token, tokenSecret, profile, done) => {
// find current user in UserModel
console.log(profile);
const currentUser = User.findOne({
googleId: profile.id
});
// create new user if the database doesn't have this user
if (!currentUser) {
const newUser = new User({
name: profile.displayName,
screenName: profile.displayName,
googleId: profile.id,
profileImageUrl: ""
})
newUser.save()
.catch((err) => console.log(err));
if (newUser) {
done(null, newUser);
}
} else {
done(null, currentUser);
}
}
)
);
Thanks for reading this and helping!!

Nodejs - Passport - Failed to serialize user into session

I am using the following library:
passport-oauth2-password-grant
What I'm trying to do is the following:
Authenticate to the API (username / password)
Get the Access token
Get the user profile from the API
Log the user in using passport
I'm using the following implementation:
PasswordGrantStrategy.prototype.userProfile = function(accessToken, done) {
return done(null, { real_name: 'Foo Baz', email: 'test#test.com' });
}
passport.use(new PasswordGrantStrategy({
tokenURL: 'http://api.local/oauth/token',
clientID: "2",
clientSecret: "",
grantType: "password",
},
function(accessToken, refreshToken, profile, done) {
return done(null, profile);
}));
function authenticate() {
return function(req, res, next) {
var username = "email#email.com";
var password = "password";
passport.authenticate('password-grant', {
username: username,
password: password
})(req, res, next);
};
}
Login to the API using username/password
It's passing the profile into the callback function for the passport.use(new PasswordGrantStrategy however, I am getting the following error:
Failed to serialize user into session
It should be serializing as I'm passing in a profile and all looks fine. Now does this mean there could be a possible issue with sessions?
You need to provide serializeUser and deserializeUser method to Passport in order for it to work.
From the official docs:
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});

LinkedIN OAuth log in trouble Nodejs

I am using LinkedIn OAuth and passport for my sign in. For whatever reason the first time I try to log in, it routes to homepage without logging in. The second time however, it logs in properly. What might be causing this problem? LinkedIn or passport?
This is the get path :
router.get('/auth/linkedin/callback', passport.authenticate('linkedin', {failureRedirect: '/', failureFlash:true}),
function (req, res, next) {
User.findOne({_id: req.user._id}, function (err, user) {
if (err) {
return next(err);
res.redirect("/")
}
user.last_login = moment();
user.save()
return res.redirect('/profile/' + user.username);
});
});
And then the passport linkedIn :
passport.use(new LinkedInStrategy({
clientID: config.linkedin.consumerKey,
clientSecret: config.linkedin.consumerSecret,
callbackURL: config.linkedin.callbackURL,
state: true,
scope: ['r_basicprofile', 'r_emailaddress']}, function (token, refreshToken, profile, done) {
...

Connect Local Users to Facebook/Twitter with PassortJS

I have an existing user base, that I want to allow them to link with their Facebook/Twitter Accounts. Looks like I can use passportjs but am having difficulty,
Right now, a url pass in their user/pass, I do a local stragety, and look up the user. Then I want to perform an authorize I presume. I get the facebook promopts asking if I want to allow, and I hit the callback with the accessToken, but I have no way to tie that token to an existing user in my db as I see now way to get the request info.
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
Users.findOne({_id: user._id}, function(err, user) {
return done(err, user);
});
});
passport.use(new LocalStrategy({ passReqToCallback: true }, function(req, username, password, done) {
Users.findOne({_id: username}, function(err, user) {
return done(null, user);
});
}
));
passport.use(new FacebookStrategy({
clientID: 'xxxx',
clientSecret: 'xxxx',
callbackURL: "http://xxxx/facebook/callback",
passReqToCallback: true
},
function(req, accessToken, refreshToken, profile, done) {
// How would I get access to the user found in the LocalStrategy here so I can associate the accessToken to the user in the db?
console.log(accessToken);
console.log(refreshToken);
var err = null;
var user = {};
return done(err, user);
}
));
server.get('/facebook', passport.authenticate('local', { failureRedirect: '/login', failureFlash: true }),
function (req, res) {
if (req && req.user) {
passport.authorize('facebook', { scope: ['publish_actions','manage_pages'] })(req, res);
}
});
server.get('/facebook/callback',
passport.authorize('facebook', { failureRedirect: '/facebook/failure', successRedirect: '/facebook/success' }),
function(req, res) {
res.redirect('/');
}
);
Assuming that the user is already logged in with the local strategy, the user should be available on the request as req.user. You can then add the facebook credential information to the existing user object.
Check to see which URL you are redirecting to on your Facebook callback and make sure that you aren't generating different sessions between the time that you log in locally and the time that you are directed to your callback from Facebook.
I had a similar issue that was driving me crazy, and it's because my redirects were different.
For example, I was navigating to http://localhost:3000 in Chrome, logging in and req.user was being set correctly. On my Facebook dev settings, and Passport config, I was redirecting to http://hostname.local:3000/auth/facebook.
As long as your local login and redirect share the same session, then req.user should be available.

Resources