Why am I getting a TokenError when authenticating with OAuth2Strategy for Passport/Node Express - node.js

I'm trying to use the OAuth2Strategy for Passport JS in conjunction with Express (4).
After I'm redirected to to login, it successfully navigates me back to my callback url, at which point I get the following error:
TokenError: Invalid client or client credentials
at OAuth2Strategy.parseErrorResponse (/www/az-avatarz-server/node_modules/passport-oauth/node_modules/passport-oauth2/lib/strategy.js:298:12)
at OAuth2Strategy._createOAuthError (/www/az-avatarz-server/node_modules/passport-oauth/node_modules/passport-oauth2/lib/strategy.js:345:16)
at /www/az-avatarz-server/node_modules/passport-oauth/node_modules/passport-oauth2/lib/strategy.js:171:43
at /www/az-avatarz-server/node_modules/passport-oauth/node_modules/passport-oauth2/node_modules/oauth/lib/oauth2.js:177:18 at passBackControl (/www/az-avatarz-server/node_modules/passport-oauth/node_modules/passport-oauth2/node_modules/oauth/lib/oauth2.js:124:9)
at IncomingMessage.<anonymous> (/www/az-avatarz-server/node_modules/passport-oauth/node_modules/passport-oauth2/node_modules/oauth/lib/oauth2.js:143:7)
at IncomingMessage.EventEmitter.emit (events.js:117:20)
at _stream_readable.js:919:16
at process._tickDomainCallback (node.js:463:13)
My passport configuration is as follows:
passport.use("avatarz", new OAuth2Strategy({
authorizationURL: authorizationURL,
tokenURL: tokenURL,
clientID: clientID,
clientSecret: clientSecret,
callbackURL: callbackURL
},
function (accessToken, refreshToken, profile, done) {
User.find({
prid: profile.prid
}, function (error, user) {
if (error) {
return done(error);
}
if (user) {
return done(null, user);
}
else {
done(error);
}
});
}
));
And my routes are as follows:
app.get('/authentication/provider', passport.authenticate("avatarz"));
app.get('/', passport.authenticate("avatarz", { failureRedirect: '/authentication/provider' }),
function (req, res) {
res.sendfile("./public/index.html");
});
Any help/advice would be greatly appreciated!

Ensure that you have activated the Google+ API at: https://console.developers.google.com

Related

Need help in getting an access-token using Passport-azure-ad npm module and OIDCStrategy

I am trying to call Microsoft Graph API from my NodeJS express webapp and I am not able to fetch an access token from AAD.
I am able to successfully login as well as able to get the user's profile,(able to get the code and id_token) and next I want to fetch the access token so that I call make the Graph Api call.
Can someone please help understand how can I fetch the access token from the OIDCStrategy?
I found the fix for the same.
passport.use(new OIDCStrategy({
identityMetadata: configAuth.creds.identityMetadata,
clientID: configAuth.creds.clientID,
responseType: configAuth.creds.responseType,
responseMode: configAuth.creds.responseMode,
redirectUrl: configAuth.creds.redirectUrl,
allowHttpForRedirectUrl: configAuth.creds.allowHttpForRedirectUrl,
clientSecret: configAuth.creds.clientSecret,
validateIssuer: configAuth.creds.validateIssuer,
isB2C: configAuth.creds.isB2C,
issuer: configAuth.creds.issuer,
passReqToCallback: configAuth.creds.passReqToCallback,
scope: configAuth.creds.scope,
loggingLevel: configAuth.creds.loggingLevel,
nonceLifetime: configAuth.creds.nonceLifetime,
nonceMaxAmount: configAuth.creds.nonceMaxAmount,
useCookieInsteadOfSession: configAuth.creds.useCookieInsteadOfSession,
cookieEncryptionKeys: configAuth.creds.cookieEncryptionKeys,
clockSkew: configAuth.creds.clockSkew,
}, (req, iss, sub, profile, access_token, refresh_token, params, done) => {
console.log(`Profile >>>> ${JSON.stringify(profile)}`);
if(!profile.oid) {
return done(new Error("No oid found"), null);
}
profile.tokens = params;
// console.log(`Access-Token >>>> ${access_token}`);
// console.log(`Refresh-Token >>>> ${refresh_token}`);
// console.log(`Profile >>>>>>>>>>>>>> ${JSON.stringify(profile)}`);
process.nextTick(() => {
findByOid(profile.oid, (err, user) => {
if(err) {
return done(err);
}
if(!user) {
users.push(profile);
return done(null, profile);
}
return done(null, user);
});
});
}));

Google Authentication using passport-google not working

Here's the code i typed.
var passport = require("passport");
var GoogleStrategy = require("passport-google-oauth").OAuth2Strategy;
// Use the GoogleStrategy within Passport.
// Strategies in Passport require a `verify` function, which accept
// credentials (in this case, an accessToken, refreshToken, and Google
// profile), and invoke a callback with a user object.
passport.use(
new GoogleStrategy(
{
clientID: '28013134812-qc5lbogacg4cf42etiruqveskh8vaqgh.apps.googleusercontent.com',
clientSecret: 'secret! i can't type secret here',
callbackURL: "www.example.com.com/auth/google/callback",
},
function (accessToken, refreshToken, profile, done) {
User.findOrCreate({ googleId: profile.id }, function (err, user) {
return done(err, user);
});
}
)
);
// GET /auth/google
// Use passport.authenticate() as route middleware to authenticate the
// request. The first step in Google authentication will involve
// redirecting the user to google.com. After authorization, Google
// will redirect the user back to this application at /auth/google/callback
app.get(
"/auth/google",
passport.authenticate("google", {
scope: ["https://www.googleapis.com/auth/plus.login"],
})
);
// GET /auth/google/callback
// Use passport.authenticate() as route middleware to authenticate the
// request. If authentication fails, the user will be redirected back to the
// login page. Otherwise, the primary route function function will be called,
// which, in this example, will redirect the user to the home page.
app.get(
"/auth/google/callback",
passport.authenticate("google", { failureRedirect: "/login" },
function (req, res) {
res.redirect("/");
})
);
ReferenceError: User is not defined
at Strategy._verify (C:\Users\hp\short.nner\server.js:64:7)
at C:\Users\hp\short.nner\node_modules\passport-oauth2\lib\strategy.js:202:24
at C:\Users\hp\short.nner\node_modules\passport-google-oauth20\lib\strategy.js:122:5
at passBackControl (C:\Users\hp\short.nner\node_modules\oauth\lib\oauth2.js:134:9)
at IncomingMessage. (C:\Users\hp\short.nner\node_modules\oauth\lib\oauth2.js:157:7)
at IncomingMessage.emit (node:events:341:22)
at endReadableNT (node:internal/streams/readable:1294:12)
at processTicksAndRejections (node:internal/process/task_queues:80:21)
I copied the above code from passport docs. Does anyone know why I am getting this error?
What actually is User here?
i think something's wrong with this code
function (accessToken, refreshToken, profile, done) {
User.findOrCreate({ googleId: profile.id }, function (err, user) {
return done(err, user);
});
}
Just put correct callback URL here callbackURL: "http://localhost:3000.com/auth/google/callback", and define User. That's it

Error at Strategy.OAuth2Strategy.parseErrorResponse - NodeJS passport google oauth2.0

I'm trying to embed google authentication in Node.js using passport and google passport-google-oauth20. The problem is that when the google callback route opens up I get:
Error
at Strategy.OAuth2Strategy.parseErrorResponse (E:\Programowanie\NodeJS\Hydronide\node_modules\passport-oauth2\lib\strategy.js:329:12)
at Strategy.OAuth2Strategy._createOAuthError (E:\Programowanie\NodeJS\Hydronide\node_modules\passport-oauth2\lib\strategy.js:376:16)
at E:\Programowanie\NodeJS\Hydronide\node_modules\passport-oauth2\lib\strategy.js:166:45
at E:\Programowanie\NodeJS\Hydronide\node_modules\oauth\lib\oauth2.js:191:18
at passBackControl (E:\Programowanie\NodeJS\Hydronide\node_modules\oauth\lib\oauth2.js:132:9)
at IncomingMessage.<anonymous> (E:\Programowanie\NodeJS\Hydronide\node_modules\oauth\lib\oauth2.js:157:7)
at emitNone (events.js:110:20)
at IncomingMessage.emit (events.js:207:7)
at endReadableNT (_stream_readable.js:1059:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
I (more or less) follow this tutorial.
Here is my code:
Routes (starting with '/auth')
'use strict'
const passport = require('passport')
const router = require('express').Router()
router.get(
'/google',
(req, res, next) => {
if (req.query.return) {
req.session.oauth2return = req.query.return
}
next()
},
passport.authenticate('google', { scope: ['email', 'profile'] })
)
router.get(
'/google/callback',
passport.authenticate('google'),
(req, res) => {
const redirect = req.session.oauth2return || '/';
delete req.session.oauth2return;
res.redirect(redirect);
}
);
module.exports = router
There is a passport configuration:
'use strict'
const passport = require('passport')
const keys = require('./keys')
const GoogleStrategy = require('passport-google-oauth20').Strategy
const userController = require('../controllers/user-controller')
const passportConfig = {
clientID: keys.google.clientId,
clientSecret: keys.google.clientSecret,
callbackURL: 'auth/google/callback',
accessType: 'offline'
}
passport.use(new GoogleStrategy(passportConfig,
(accessToken, refreshToken, profile, done) => {
console.log(accessToken, refreshToken, profile, done)
userController.getUserByExternalId('google', profile.id)
.then(user => {
if (!user) {
userController.createUser(profile, 'google')
.then(user => {
return done(null, user)
})
.catch(err => {
return done(err)
})
}
return done(null, user)
})
.catch(err => {
return done(err)
})
}))
passport.serializeUser((user, cb) => {
cb(null, user)
})
passport.deserializeUser((obj, cb) => {
cb(null, obj)
})
As you can see I've added console.log in the new GoogleStrategy second parameter function, but it never fires.
//EDIT
I noticed that instead of assign require('passport-google-oauth20').Strategy I used require('passport-google-oauth20'). But fixing it doesn't chang anything, still the same error.
What I can add to a question is that in my main fail I call
// sets passport config
require('./config/jwt-auth')
require('./config/google-auth')
// initialize passport
app.use(passport.initialize())
So I don't expect anything wrong in there.
You have to specify the full url in the callbackURL section of the strategy:
for example: when if running the code locally on localhost:3000 with code like this:
passport.use(new googleStrategy({
clientID:keys.clientID,
clientSecret:keys.clientSecret,
callbackURL:'auth/google/callback'
},(accessToken,refreshToken, profile,done)=>{
console.log(accessToken);
console.log(refreshToken);
console.log(profile);
}
));
app.get('/auth',passport.authenticate('google',{
scope:['profile','email']
}));
app.get('/auth/google/callback',
passport.authenticate('google'));
The above code will surely throw a TokenError: Bad request. You have to pass the complete URl to have a final code like shown below:
passport.use(new googleStrategy({
clientID:keys.clientID,
clientSecret:keys.clientSecret,
callbackURL:'http://localhost:3000/auth/google/callback'
},(accessToken,refreshToken, profile,done)=>{
console.log(accessToken);
console.log(refreshToken);
console.log(profile);
}
));
app.get('/auth',passport.authenticate('google',{
scope:['profile','email']
}));
app.get('/auth/google/callback',
passport.authenticate('google'));
You can get help by putting some console.log inside your Oauth and Strategy under node modules, Specifically around the line on which you are getting error in logs.
E:\Programowanie\NodeJS\Hydronide\node_modules\passport-oauth2\lib\strategy.js
E:\Programowanie\NodeJS\Hydronide\node_modules\oauth\lib\oauth2.js
This will help you to get the root cause of parsing error . Seems like there is some problem with request/response data.
I solved the issue by checking this route
app.get('/auth',passport.authenticate('google',{
scope:['profile','email']
}));
I was trying to do something to new users and for that I was trying to get the users from the database if I get that I will do that work otherwise simply redirect to somewhere but the problem I faced is
you can check this route by consoling the log
const express = require('express');
const router = express.Router();
const { User } = require('../models/user.model');
const jwt = require('jsonwebtoken');
const config = require('../config/config.json');
const role = require('../lib/role');
const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth20').Strategy;
router.use(passport.initialize());
passport.serializeUser((user, cb) => {
cb(null, user);
});
passport.deserializeUser((obj, cb) => {
cb(null, obj);
});
passport.use(new GoogleStrategy({
clientID: "sssssssssssssssssssssssssss",
clientSecret: "Vsssssssssssssss",
callbackURL: "http://localhost:4000/api/auth/google/callback"
},
(request, accessToken, refreshToken, profile, cb) => {
User.findOne({ email: profile.emails[0].value }, (err, user) => {
if (err) {
cb(err); // handle errors!
}
if (!err && user !== null) {
cb(err, user);
}
else {
user = new User({
googleId: profile.id,
email: profile.emails[0].value,
firstname: profile.name.givenName,
lastname: profile.name.familyName,
role: role.Client,
isActive: true,
isGain: false,
});
user.save((err) => {
if (err) {
cb(err); // handle errors!
} else {
cb(null, user);
}
});
}
});
}
));
router.get('/', passport.authenticate('google', { session: false, scope: ['profile', 'email'] }));
// callback
router.get('/callback', passport.authenticate('google', { failureRedirect: '/failed' }),
(req, res) => {
const token = jwt.sign({ userId: req.user._id, email: req.user.email, role: req.user.role }, config.secret_key, { expiresIn: '10 h' })
res.status(200).json({ success: true, token, expireIn: `${new Date().getTime() + 120000}` })
}
);
//failed auth google
router.get('/failed', async (req, res) => { res.status(404).send('erreur authentification') })
module.exports = router;
In passport.js you need to change callbackURL from 'auth/google/callback' to '/auth/google/callback'. Do not forget to add '/' before auth.
passport.use(new googleStrategy({
clientID:keys.clientID,
clientSecret:keys.clientSecret,
callbackURL:'/auth/google/callback'
},(accessToken,refreshToken, profile,done)=>{
console.log(accessToken);
console.log(refreshToken);
console.log(profile);
}
));
passport.use(new GoogleStrategy({
clientID: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
callbackURL: "http://localhost:3000/auth/google/home"
},
function(accessToken, refreshToken, profile, cb) {
console.log(profile);
User.findOrCreate({ username: profile.displayName, googleId: profile.id },
function (err, user) {
return cb(err, user);
});
}));

passport-facebook Strategy.parseErrorResponse

I am trying to set up Facebook authentication and I am getting an error whenever the callback function is called it throws a Strategy.parseErrorResponse at /node_modules/passport-facebook/lib/strategy.js:196:12
There is no message telling me what was wrong. I checked to make sure my clientID and secret were correct (as I seen this may happen if they are wrong).
passport.use(new FacebookStrategy({
clientID: myId,
clientSecret: mySeceret,
callbackURL: callBackUrl,
passReqToCallback : true
}, (req, accessToken, refreshToken, profile, done) => {
process.nextTick(() => {
if (req.user) {
done(null, req.user);
if (!req.user.facebookId) {
req.user.facebookId = profile.id;
req.user.save().then(() => {
done(null, req.user);
});
} else {
done(null, req.user);
}
} else {
User.find({where: {facebookId: profile.id}}, function (err,user) {
return done(err, user);
});
}
});
}));
my routes
app.get('/auth/facebook', passport.authenticate('facebook', { scope: 'email' }));
app.get('/auth/facebook/callback',
passport.authenticate('facebook', { failureRedirect: '/login' }),
function (req, res) {
res.redirect('/');
});
full stack
Error
at Strategy.parseErrorResponse (/node_modules/passport-facebook/lib/strategy.js:196:12)
at Strategy.OAuth2Strategy._createOAuthError (/node_modules/passport-oauth2/lib/strategy.js:376:16)
at /node_modules/passport-oauth2/lib/strategy.js:166:45
at /node_modules/oauth/lib/oauth2.js:191:18
at passBackControl (/node_modules/oauth/lib/oauth2.js:132:9)
at IncomingMessage.<anonymous> (/node_modules/oauth/lib/oauth2.js:157:7)
at emitNone (events.js:91:20)
at IncomingMessage.emit (events.js:188:7)
at endReadableNT (_stream_readable.js:975:12)
at _combinedTickCallback (internal/process/next_tick.js:80:11)
at process._tickDomainCallback (internal/process/next_tick.js:128:9)
Also, it looks like key is getting passed because it contains the I can see the route that is being called /auth/facebook/callback?code="someReallyLongKey"
I run into exactly the same issue today. It occurred because my server could not connect to the Mongo database. I restarted the mongod service and everything started to work as expected

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) {
...

Resources