Skip to content

Instantly share code, notes, and snippets.

@camperbot
Forked from ShaunSHamilton/auth.js
Last active August 20, 2022 21:10
Show Gist options
  • Save camperbot/183e968f0e01d81dde015d45ba9d2745 to your computer and use it in GitHub Desktop.
Save camperbot/183e968f0e01d81dde015d45ba9d2745 to your computer and use it in GitHub Desktop.
Advanced Node and Express - Implementation of Social Authentication III
const passport = require('passport');
const LocalStrategy = require('passport-local');
const bcrypt = require('bcrypt');
const ObjectID = require('mongodb').ObjectID;
const GitHubStrategy = require('passport-github').Strategy;
module.exports = function (app, myDataBase) {
passport.serializeUser((user, done) => {
done(null, user._id);
});
passport.deserializeUser((id, done) => {
myDataBase.findOne({ _id: new ObjectID(id) }, (err, doc) => {
if (err) return console.error(err);
done(null, doc);
});
});
passport.use(new LocalStrategy(
function (username, password, done) {
myDataBase.findOne({ username: username }, function (err, user) {
console.log('User ' + username + ' attempted to log in.');
if (err) { return done(err); }
if (!user) { return done(null, false); }
if (!bcrypt.compareSync(password, user.password)) { return done(null, false); }
return done(null, user);
});
}
));
passport.use(new GitHubStrategy({
clientID: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET,
callbackURL: 'https://boilerplate-advancednode.your-username.repl.co/auth/github/callback'
},
function (accessToken, refreshToken, profile, cb) {
console.log(profile);
myDataBase.findAndModify(
{ id: profile.id },
{},
{
$setOnInsert: {
id: profile.id,
name: profile.displayName || 'John Doe',
photo: profile.photos[0].value || '',
email: Array.isArray(profile.emails) ? profile.emails[0].value : 'No public email',
created_on: new Date(),
provider: profile.provider || ''
},
$set: {
last_login: new Date()
},
$inc: {
login_count: 1
}
},
{ upsert: true, new: true },
(err, doc) => {
return cb(null, doc.value);
}
);
}
));
};
@Ankeet-Ak
Copy link

I've passed this test but still unable to login because I get this error when I authorize access to my app to view my Github account.
TokenError: The client_id and/or client_secret passed are incorrect. I've double checked they are perfectly fine. Plz help! Below is the full list of error generated:
TokenError: The client_id and/or client_secret passed are incorrect.
at Strategy.OAuth2Strategy.parseErrorResponse (/home/runner/boilerplate-advancednode/node_modules/passport-oauth2/lib/strategy.js:373:12)
at Strategy.OAuth2Strategy._createOAuthError (/home/runner/boilerplate-advancednode/node_modules/passport-oauth2/lib/strategy.js:420:16)
at /home/runner/boilerplate-advancednode/node_modules/passport-oauth2/lib/strategy.js:177:45
at /home/runner/boilerplate-advancednode/node_modules/passport-github/lib/strategy.js:77:16
at /home/runner/boilerplate-advancednode/node_modules/oauth/lib/oauth2.js:209:7
at passBackControl (/home/runner/boilerplate-advancednode/node_modules/oauth/lib/oauth2.js:134:9)
at IncomingMessage. (/home/runner/boilerplate-advancednode/node_modules/oauth/lib/oauth2.js:157:7)
at IncomingMessage.emit (events.js:387:35)
at endReadableNT (internal/streams/readable.js:1317:12)
at processTicksAndRejections (internal/process/task_queues.js:82:21)

@dwisatriow
Copy link

@Ankeet-Ak Can I see your auth.js code?

@Ankeet-Ak
Copy link

@Ankeet-Ak Can I see your auth.js code?

const passport = require('passport');
const bcrypt = require('bcrypt');
const LocalStrategy = require('passport-local');
const ObjectID = require('mongodb').ObjectID;
const GithubStrategy = require('passport-github');

module.exports = function (app, myDataBase) {
passport.serializeUser((user, done) => {
done(null, user._id);
});

passport.deserializeUser((id, done) => {
  myDataBase.findOne({_id: new ObjectID(id)}, (err, doc) => {
  done(null, doc);
 });
});

passport.use(new LocalStrategy(

function(username, password, done) {
myDataBase.findOne({ username: username }, function (err, user) {
console.log('User '+ username +' attempted to log in.');
if (err) { return done(err); }
if (!user) { return done(null, false); }
if (!bcrypt.compareSync(password, user.password)) {
return done(null, false);
}
return done(null, user);
});
}
));

passport.use(new GithubStrategy({
clientID: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET,
callbackURL: 'https://boilerplate-advancednode.ankeetsingh.repl.co/auth/github/callback'
},
function(accessToken, refreshToken, profile, cb) {
console.log(profile);
myDataBase.findandModify(
{ id: profile.id },
{},
{
$setOnInsert: {
id: profile.id,
name: profile.displayName || 'John Doe',
photo: profile.photos[0].value || '',
email: Array.isArray(profile.emails) ?
profile.emails[0].value : 'No public email',
created_on: new Date(),
provider: profile.provider || ''
},
$set: {
last_login: new Date()
},
$inc: {
login_count: 1
}
},
{upsert: true, new: true},
(err, doc) => {
return cb(null, doc.value);
}
);
}
));

}

@dwisatriow
Copy link

@Ankeet-Ak Looks like you missing the .Strategy when requiring passport-github. Try like this

const GitHubStrategy = require('passport-github').Strategy;

@Ankeet-Ak
Copy link

@Ankeet-Ak Looks like you missing the .Strategy when requiring passport-github. Try like this

const GitHubStrategy = require('passport-github').Strategy;

Thanks for the help! But I moved on to further tests since FCC passed me in this test and now I'm stuck on 'Authentication with Socket.io'. So, I'm little messed up right now and can only see if your suggestion works after few days! BTW I've also added my problem with 'Authentication with socket.io' on that thread. If you can help me there too then please!

@Xavier-Pierre-dev
Copy link

Hello, I think maybe we should use :
const GitHubStrategy = require('passport-github2').Strategy;

because if we refer to the documentation here : https://www.passportjs.org/packages/passport-github2/
The author of Passport-Github has not maintained the original module for a long time. Features in his module don't work since Github upgraded their API to version 3.0. We forked it and re-published it to NPM with a new name passport-github2.

but even when I use :
const GitHubStrategy = require('passport-github').Strategy;
this is working so I guess it's fine.

So for
const GitHubStrategy = require('passport-github2').Strategy;
or
const GitHubStrategy = require('passport-github').Strategy;
I'm not sur about wich one we should really use.



also since https://www.freecodecamp.org/learn/quality-assurance/advanced-node-and-express/how-to-put-a-profile-together
people certainly put that on them profile.pug
h2.center#welcome Welcome, #{username}!
so I guess it's will be better if inside the passport.use(new GitHubStrategy({ if we use

          $setOnInsert: {
            id: profile.id,
            username: profile.username,
            name: profile.displayName || 'John Doe',
            photo: profile.photos[0].value || '',
            email: Array.isArray(profile.emails) ? profile.emails[0].value : 'No public email',
            created_on: new Date(),
            provider: profile.provider || ''
          },

So that we have the username from github and then the username will be display on the profile page when we log in using github



Also I think this is important to explain inside the curriculum that if we want to use

  cookie: { secure: true }

with replit we should use also :

app.set('trust proxy', 1);
app.use(session({
  secret: process.env['SESSION_SECRET'],
  resave: true,
  saveUninitialized: true,
  cookie: { secure: true }
}));
app.use(passport.initialize());
app.use(passport.session());

and specify that : app.set('trust proxy', 1); is required because we are on replit so with a proxy but if we don't have proxy we should not use this option.
Source :

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment