Unknown authentication strategy "github" - javascript

Online authentication of GitHub is not working. I've registered the new app in GitHub and still the application won't redirect to OAuth.
The following code I've written and getting Error:Unknown authentication strategy "github"
const passport = require('passport');
const bcrypt = require('bcrypt');
module.exports = function (app, db) {
app.route('/')
.get((req, res) => {
res.render(process.cwd()+'/views/pug/index', {title: 'Hello', message: 'Please login',showLogin: true, showRegistration: true});
});
app.route('/login')
.post(passport.authenticate('local',{ failureRedirect: '/' }),(req,res)=>{
res.redirect('/profile');
});
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect('/');
}
app.route('/profile')
.get(ensureAuthenticated, (req,res) => {
res.render(process.cwd() + '/views/pug/profile',{username:req.user.username});
});
app.route('/logout')
.get((req, res) => {
req.logout();
res.redirect('/');
});
app.route('/register')
.post((req, res, next) => {
var hash = bcrypt.hashSync(req.body.password, 12);
db.collection('users').findOne({ username: req.body.username }, function (err, user) {
if(err) {
next(err);
} else if (user) {
res.redirect('/');
} else {
db.collection('users').insertOne(
{username: req.body.username,
password: hash},
(err, doc) => {
if(err) {
res.redirect('/');
} else {
next(null, user);
}
}
)
}
})},
passport.authenticate('local', { failureRedirect: '/' }),
(req, res, next) => {
res.redirect('/profile');
}
);
/*GitHub OAuth*/
app.route('/auth/github')
.get(passport.authenticate('github'));
app.route('/auth/github/callback')
.get(passport.authenticate('github', { failureRedirect: '/' }), (req,res) => {
res.redirect('/profile');
});
/*End of GitHub OAuth*/
app.use((req, res, next) => {
res.status(404)
.type('text')
.send('Not Found');
});
}
It seems I have missing something or anything else for OAuth. The strategy wasn't defined in my side I just accessing default strategy for GitHub.

You have to configure passport github strategy in your script. https://github.com/jaredhanson/passport-github
var GitHubStrategy = require('passport-github').Strategy;
passport.use(new GitHubStrategy({
clientID: GITHUB_CLIENT_ID,
clientSecret: GITHUB_CLIENT_SECRET,
callbackURL: "http://127.0.0.1:3000/auth/github/callback"
},
function(accessToken, refreshToken, profile, cb) {
User.findOrCreate({ githubId: profile.id }, function (err, user) {
return cb(err, user);
});
}
));

Related

Passing state value to passport.authenticate function for GoogleOAuthStrategy

I need to get referralCode which is present as a param on the request URL. I am getting a forbidden error with status code 402 with the following code. On passing this referralcode in passport.authenticate as a state variable the code isn't working. It works fine without referralcode.
passport.use(
new GoogleStrategy(
{
clientID: secrets.GOOGLE_CLIENT_ID,
clientSecret: secrets.GOOGLE_SECRET_KEY,
callbackURL: `${config.api_host}/v1/user/login/google/callback`,
passReqToCallback: true,
scope: ['email', 'profile'],
state: true
},
async (req, accessToken, refreshToken, profile, cb) => {
cb(null, profile);
}
)
);
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((id, done) => {
done(null, id);
});
router.get(
"/login/google/:referralcode",
function (req, res, next) {
passport.authenticate("google", {
scope: ["email", "profile"],
state: req.params.referralcode,
})(req, res, next)
},
);
router.get(
"/login/google/callback",
passport.authenticate("google", {
passReqToCallback: true,
failureRedirect: failureRedirectRoute,
}), // If I comment above two lines, it works fine.
async (req, res, next) => {
try {
const result = await googleSignInAuthCallback(req, res, next);
// console.log("req", req);
return res.status(200).json(result);
} catch (err) {
console.log(err, "ERR");
}
}
);

Why isAuthenticated return false in passport.js local strategy after successful login the user

I have the following code to authenticate through the passport-local strategy:
routes.post("/login", passport.authenticate("local"), (req, res) => {
res.json(req.user);
});
function ensureAuth(req, res, next) {
console.log(req.isAuthenticated());
if (req.isAuthenticated()) {
next();
} else {
req.flash("info", "You must be logged in to see this page");
res.redirect("/login");
}
}
routes.get("/edit", ensureAuth, (req, res) => {
res.sendStatus(200);
});
routes.post("/edit", ensureAuth, (req, res, next) => {
req.user.username = req.body.username;
req.user.bio = req.body.bio;
req.user.email = req.body.email;
req.user.save((err) => {
if (err) {
return next(err);
} else {
res.send({
success: "true",
info: "Profile updated",
});
}
});
});
I can't figure out why this is happening? Why won't it authenticate?
I can't see your passport local configuration and I send a sample for local Authentication by passport local I hope help you :)
login route:
router.post('/login', loginController.process);
controller loginController.process :
async process(req, res, next) {
try {
passport.authenticate('local.login', async (err, user) => {
// User not Exist
if (!user) return this.back(req, res);
req.logIn(user, (err) => {
if (req.body.remember) {
user.setRememberToken(res);
}
return res.redirect('/');
});
})(req, res, next);
} catch (e) {
next(e);
}
}
}
passport configuration :
passport.use('local.login', new localStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true,
}, async (req, email: string, password: string, done) => {
// Select User Where email
const user = await userService.findOne({email});
// Check user Exist or Incorrect Password
if (!user || !user.comparePassword(password)) return done(req.flash('global_error', req.__('typeScript.app.passport.passport-local.wrong')), null);
done(null, user);
}));

Login and Register not working node.js MongoDB

my app.js not working as i think. so, after i register for a new one, it will send to my MongoDB and take me directly to the page2 but it is taking back to the home page and when i type in and click on login, it will have the error "This site can’t be reached" on localhost:8080/processLogin. im not sure how to fix them. i think errors are on function checkLogin(req, res, user, password) and app.post('/processReg', function(req, res)
app.js
var express = require('express'),
handlebars = require('express-handlebars').create({ defaultLayout: 'main' }),
cookieParser = require('cookie-parser'),
sessions = require('express-session'),
bodyParser = require('body-parser'),
https = require('https'),
fs = require('fs'),
md5 = require('md5'),
mongoose = require('mongoose'),
credentials = require('./credentials'),
Users = require('./models/uCredentials.js');
// load env variables
const dotenv = require("dotenv");
dotenv.config();
var app = express();
//db connection
mongoose
.connect(process.env.MONGO_URI, {
useUnifiedTopology: true,
useNewUrlParser: true,
})
.then(() => console.log("DB Connected"));
mongoose.connection.on("error", (err) => {
console.log(`DB connection error: ${err.message}`);
});
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser(credentials.cookieSecret));
app.use(sessions({
resave: true,
saveUninitialized: false,
secret: credentials.cookieSecret,
cookie: { maxAge: 3600000 },
}));
app.engine('handlebars', handlebars.engine);
app.set('view engine', 'handlebars');
app.set('port', process.env.PORT || 3100);
app.get('/', function(req, res) {
res.render('login');
});
function checklogin(req, res, user, password) {
//implementation of this function
Users.findOne({ uname: user }, function(err, user) {
if (err) {
console.log(err);
res.send({ 'message': 'Login successfully!' });
} else {
res.send({ 'message': 'Username or password do not match our records. Please try again or register if you are a new user!' });
}
});
};
app.post('/processLogin', function(req, res) {
//Determine if user is registering
if (req.body.buttonVar == 'login') {
checklogin(req, res, req.body.uname.trim(), req.body.pword.trim())
} else {
res.redirect(303, 'register');
}
});
app.post('/processReg', function(req, res) {
//implement this end point
if (req.body.pword.trim() == req.body.pword2.trim()) {
const user = new Users({ uname: req.body.uname, pass: req.body.pword });
console.log('Creating new user ', req.body);
user.save((err, toDB) => {
if (err) {
return res.status(400).json({ error: err });
}
res.status(200).json({ user: toDB });
});
res.redirect(303, 'page2');
} else {
res.render('register', { message: 'The two passwords are not the same !' });
}
});
app.get('/home', function(req, res) {
if (req.session.userName) {
res.render('home');
} else {
res.render('login', { message: 'Please login to access the home page' });
}
});
app.get('/page2', function(req, res) {
if (req.session.userName) {
res.render('page2');
} else {
res.render('login', { message: 'Please login to access the second page' });
}
});
app.get('/register', function(req, res) {
res.render('register');
});
app.get('/logout', function(req, res) {
delete req.session.userName;
res.redirect(303, '/');
});
app.listen(app.get('port'), function() {
console.log('Express started on http://localhost:' + app.get('port') + '; press Ctrl-C to terminate');
});
process.on('unhandledRejection', error => {
// Will print "unhandledRejection err is not defined"
console.log('unhandledRejection', error.message);
});
callback logic for findOne query is wrong. check this out async/await For checkLoging function try using this:
async function checklogin(req, res, user, password) {
try {
//implementation of this function
const user = await Users.findOne({ uname: user }).exec();
if (!user) {
res.send({ 'message': 'Username or password do not match our records. Please try again or register if you are a new user!' });
}
res.send({ 'message': 'Login successfully!' });
} catch (err) {
console.log(err.message)
}
};
If you don't want to use Async/await (which I recomend for mongodb queries) you can use this:
function checklogin(req, res, user, password) {
//implementation of this function
Users.findOne({ uname: user }, function(err, user) {
if (err) {
console.log(err);
res.send({ 'message': 'Username or password do not match our records. Please try again or register if you are a new user!' });
}
res.send({ 'message': 'Login successfully!' });
});
};

How to use passport to authenticate users and admins

Im running a local strategy in passport and I have had an issue where it seems to authenticate users fine and I can have that user persisted across the site in a session, but not admins. I have the user and admin account under separate collections in MongoDB.I have tried plenty of different routes like having different passports for admin and user and having different databases for admin and users to no avail. I have come to a stand still. I would appreciate an advice!
//Passport.js
const LocalStrategy = require('passport-local').Strategy;
const mongoose = require('mongoose')
const bcrypt = require('bcrypt')
// Loads in user model
const User = require('../models/userModel')
//Loads in the admin model
const Admin = require('../models/adminModel')
module.exports = function (authUser){
authUser.use(
'authUser',new LocalStrategy({usernameField: 'username'}, (username, password, done)=>{
//Match user
const user = User.findOne({username: username})
.then(user=>{
if(!user){
return done(null, false, {message: 'Incorrect Username'})
}
//Match password
bcrypt.compare(password, user.password, (err, isMatch)=>{
if(err) throw err;
if (isMatch) {
return done(null, user)
}else {
return done(null, false, {message: 'Incorrect password'})
}
})
})
.catch(err=>console.log(err));
})
)
authUser.serializeUser((user, done) =>{
done(null, user.id);
});
authUser.deserializeUser((id, done) =>{
User.findById(id, (err, user) => {
done(err, user);
});
});
authUser.use(
'admin',new LocalStrategy({usernameField: 'username'}, (username, password, done)=>{
//Match user
const admin = Admin.findOne({username: username})
.then(admin=>{
if(!admin){
return done(null, false, {message: 'Incorrect Username'})
}
//Match password
bcrypt.compare(password, admin.password, (err, isMatch)=>{
if(err) throw err;
if (isMatch) {
return done(null, admin)
}else {
return done(null, false, {message: 'Incorrect password'})
}
})
})
.catch(err=>console.log(err));
})
)
authUser.serializeUser((admin, done) =>{
done(null, admin.id);
});
authUser.deserializeUser((id, done) =>{
Admin.findById(id, (err, admin) => {
done(err, admin);
});
});
}
//Authenticate.js
module.exports = {
checkAuthenticated: function(req, res, next) {
if (req.isAuthenticated()) {
return next()
}
// req.flash('error_msg', 'please login to view this resource')
res.redirect('/Users/Login')
},
checkNotAuthenticated: function(req, res, next) {
if (req.isAuthenticated()) {
return res.redirect('/')
}
// req.flash('error_msg', 'please login to view this resource')
return next()
},
checkAdminAuthenticated: function(req, res, next) {
if (req.isAuthenticated()) {
return next()
}
// req.flash('error_msg', 'please login to view this resource')
res.redirect('http://localhost:3000/Admin/SignIn')
}
}
//Snippet from adminRoute.js
const passport = require('passport')
require('../config/passport.js')(passport)
app.get("/SignIn", checkNotAuthenticated,(req,res) =>{
res.render("adminLogin.ejs")
})
app.get('/Orders', checkAdminAuthenticated, (req, res) => {
Request.find({}).then(results => {
res.render('orders.ejs', {
Orders: results
});
})
})
// Login Handle
app.post('/SignIn', checkNotAuthenticated, (req,res, next)=>{
passport.authenticate('admin',{
successRedirect: '/AdminPage', //On success redirect to home
failureRedirect: '/Admin/SignIn', //On failure redirect back to login page
session: true,
failureFlash: true
})(req,res,next);
})
module.exports = app
//Snippet from userRoute.js
const passport = require('passport')
const authUser = new passport.Passport();
require('../config/passport.js')(authUser)
// DB config
const userDB = require('../config/keys').MongoURI
const User = require('../models/userModel')
app.get("/Login", checkNotAuthenticated,(req,res) =>{
res.render("login.ejs")
})
app.delete('/logout', (req, res) => {
req.logOut()
res.redirect('/Users/Login')
})
app.get('/Register', checkNotAuthenticated, (req,res)=>{
res.render("register.ejs")
})
// Login Handle
app.post('/Login', checkNotAuthenticated,(req,res, next)=>{
authUser.authenticate('authUser',{
successRedirect: '/', //On success redirect to home
failureRedirect: '/Users/Login', //On failure redirect back to login page
session: true,
failureFlash:true
})(req,res,next);
})
module.exports = app
// snippet from app.js
const passport = require('passport')
const authUser = new passport.Passport();
require('./config/passport.js')(authUser)
app.use(authUser.initialize())
app.use(authUser.session())
app.use('/Users', require('./routes/userRoute'))
app.use('/Admin', require('./routes/adminRoute'))

Passport JS auth middleware issue

I am implementing auth using passport js and database is mysql. My successRedirect route is '/main' and in the main route, I have added a middleware (isAuthenticated). But the issue is that, after entering valid credentials, I am not being redirected to '/main', instead, it just timeouts. I tried without adding middleware to '/main' route and it works fine.
var isAuthenticated = function(req, res, next) {
if (req.isAuthenticated()) {
return next;
}
res.redirect("/login")
}
// AUTH Implementation
app.use(session( {
secret: "asdnoifjasofijmaofmjkneknf",
resave: false,
saveUninitialized: false
}))
app.use(passport.initialize())
app.use(passport.session())
passport.use(new localStrategy(
function(username, password, done) {
connection.query("SELECT password FROM user" +
" WHERE email = ?", [username], function (err, results, fields) {
if (err) {
console.log(err);
}
else if (results.length === 0) {
done(null, false);
}
else {
console.log("Results");
console.log(results[0]);
hashedPassword = results[0].password;
bcrypt.compare(password, hashedPassword, function (err, response) {
if (response) {
console.log("True");
return done(null, true);
}
else {
console.log("False");
return done(null, false);
}
})
}
})
}
));
passport.serializeUser(function(ID, done) {
done(null, ID);
});
passport.deserializeUser(function(ID, done) {
connection.query("SELECT * FROM user WHERE userID = ?", [ID], function (err, results, fields) {
if (err) throw err;
else if (results.length === 0) done(null, false);
else {
done(null, results[0]);
}
})
done(null, ID);
});
app.post("/login", passport.authenticate('local', {
successRedirect: "/main",
failureRedirect: "/login"
}))
app.get("/main", isAuthenticated, function(req, res) {
res.send("In the main page");
})
app.post("/login", passport.authenticate('local', {
successRedirect: "/main",
failureRedirect: "/login"
}))
Help me out.
You need execute next function instead of return it.
var isAuthenticated = function(req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect("/login")
}

Categories

Resources