How to configure route for oauth callback in Node.js - javascript

This works perfectly fine in the server.js:
app.get('/auth/google/callback',
passport.authenticate('google', {
failureRedirect: '/login'
}),
(req, res) => {}
);
But the following doesn't when used in route.js:
exports.googleCallback = function(req, res, next) {
passport.authenticate('google', { failureRedirect: '/login' });
const handler = function(req, res) {
// Successful authentication, redirect home.
res.redirect('/');
};
handler(req, res, next);
};
I have the following in route.js:
app.route(path + 'auth/google').get(auth.googleLogin);
What happens:
The second code directly goes to / path without waiting for Passport Google strategy to completely execute.
If I remove res.redirect('/'); It does not go anywhere and keep loading.

This worked just fine:
exports.googleCallback = function(req, res, next) {
passport.authenticate('google', { failureRedirect: '/login' })(req, res, next);
};
Added callback method on the passport.

Related

how can handle multpile oauth request from frondend in single routr

IS there any way i can dynamic take the platform info and process them,even when i tried accessing the value outside the function it is not working since it is a single route file
router.get(
"/:platform",
function data(req, res, next) {
var platform = req.params.platform;
next();
},
passport.authenticate("google", { scope: ["email"] })
);
You can save the data in req and then run the middleware manually
This should work, but I didn't test it
router.get(
"/:platform",
function data(req, res, next) {
req.platform = req.params.platform;
next();
},
(req, res, next) => passport.authenticate(req.platform, { scope: ["email"] })(req, res, next)
);

NodeJS Passport redirect

I am trying to implement user redirection with Passport on NodeJS and Express Backend script. The issue that I am facing is that my login page is not my default home page but it's rather this:
localhost:3000/login
I've managed to make it so that if user is not registered, he cannot access other pages such as /index or /dashboard but something breaks when I try to access hard-coded urls such as:
If I enter localhost:3000/ I can gain access to the default index.html page even if I'm not logged in. Just to clarify - localhost:3000/index == localhost:3000.
If I decide to manipulate the route like this: localhost:3000/Example/pages/index.html or localhost:3000/Example/pages/dashboard.html it would allow me to access the pages even if I am logged in.
My question is, how can I restrict users to manipulate the route to the default homepage and any other pages which have not been declared in the Node Backend?
My Node Routes Code:
app.get('/login',
function(req, res){
res.sendFile(path.join(__dirname + '/login.html'));
});
app.get('/index', isLoggedIn,
function(req, res){
res.sendFile(path.join(__dirname + '/index.html'));
});
app.post('/login',
passport.authenticate('local', { failureRedirect: '/login' }),
function(req, res) {
res.redirect('/index');
});
app.post('/login',
passport.authenticate('local', { failureRedirect: '/login' }),
function(req, res) {
res.redirect('/index');
});
I've tried using this:
app.use(function(req, res, next) {
if (req.session.user == undefined) {
return res.render('/login', { failureRedirect:'/login' });
}
else {
next();
}
});
but I receive an error: No default engine was specified and no extension was provided. I don't want to use JADE or Handlebars or anything else as an engine, just static HTML.
How can I restrict the route manipulation without having to define the rest of my node pages as app.get(/something, function(req,res){});
You can make a passport middleware to check if the user is authenticated
isAuthenticated = (req, res, next) => {
if (req.isAuthenticated()) {
return next();
}
res.redirect('/login');
};
And then you can do this
app.get('/someroute', isAuthenticated, (req, res)=>{
// do what you want
});

React Router intercepting API call to Express server

I'm using React Router with Passport.js to set up Facebook login. I've set up the express routes and passport config, but every time I hit the
<a href="/api/auth/facebook"> link on my client side, it makes a request to RR because of my express app with this line:
app.get('/*', function(req, res) {
res.sendFile(path.resolve(__dirname, '../client', 'build', 'index.html'))
});
As I am making a call to the server side route, it returns this error:
Warning: [react-router] Location "/api/auth/facebook" did not match any routes
How can I bypass React Router for this one particular route?
my user_routes.js file looks like:
'user strict';
var bodyparser = require('body-parser');
var User = require('../models/User.js');
module.exports = function loadUserRoutes(router, passport) {
router.use(bodyparser.json());
router.get('/auth/facebook', passport.authenticate('facebook', {
session: false,
successRedirect: '/chat',
failureRedirect: '/'
}));
router.get('/auth/facebook/callback', passport.authenticate('facebook', {
session: false,
successRedirect: '/chat',
failureRedirect: '/'
}));
router.post('/sign_up', passport.authenticate('local-signup', { session: false}), function(req, res) {
res.json(req.user);
});
router.post('/sign_in', passport.authenticate('local-login', { session: false}), function(req, res) {
res.json(req.user);
});
router.get('/signout', function(req, res) {
req.logout();
res.end();
});
//get auth credentials from server
router.get('/load_auth_into_state', function(req, res) {
res.json(req.user);
});
// get usernames for validating whether a username is available
router.get('/all_usernames', function(req, res) {
User.find({'local.username': { $exists: true } }, {'local.username': 1, _id:0}, function(err, data) {
if(err) {
console.log(err);
return res.status(500).json({msg: 'internal server error'});
}
res.json(data);
});
})
};
In express routes are matches in the order they get defined.
So before your /* route you need something to handle api requests.
app.get('/api/auth/facebook', passport.authenticate('facebook'))
app.get('/*', function(req, res) {
res.sendFile(path.resolve(__dirname, '../client', 'build', 'index.html'))
});

stacking of routes in node.js

var express = require('express');
var router = express.Router();
router.use(function(req, res, next){
console.log(req.user)
if(!req.user){
res.redirect('/login');
}else{
res.locals.username = req.user.username;
return next();
}
});
//this won't work
router.get('/register', function(req, res, next) {
res.render('register');
});
The first block make sense and it's working,I able to have a login system with protected routes. But in the same time it ruined my second bit, it will show the login page althought I try to nagivate to localhost:3000/register.
When you're using router.use() you're telling the router to use that function middleware in all the next roter.get() routes. So here, the order makes sense. If you care about order you can do what #bloodyKnuckles do. Or if you want to keep that pattern for your routes you can do the following :
// Routes that don't need authorization like register
router.get('home',...);
router.get('register',...);
// Use your authorization middleware
router.use(function(req, res, next){
console.log(req.user)
if(!req.user){
res.redirect('/login');
}else {
res.locals.username = req.user.username;
return next();
}
});
// At this point you're using the authorization middleware.
// Any routes declared from here will call authorization middleware before its handler.
router.get('profile', ...);
Use the express route middleware option to distinguish protected routes from unprotected routes.
// unprotected routes (no auth middleware)
router.get('/login', function(req, res, next) {
res.render('login');
});
router.get('/register', function(req, res, next) {
res.render('register');
});
// protected route (see auth middleware here)
router.get('/userinfo', authorize, function(req, res, next) {
res.render('userinfo');
});
function authorize (req, res, next){
console.log(req.user)
if(!req.user){
res.redirect('/login');
}else{
res.locals.username = req.user.username;
return next();
}
}
Include your authorization middleware ONLY in the protected routes:
router.get(path, [middleware (optional),] callback)

express-session req.user is undefined

I'm trying to use express session to login users. I'd like users to be able to go to a profile page and view their user data if they have logged in.
I've been stuck here for days. On line 33 of my routes.js file, in my /profile GET route, req.user is undefined. But on line 27 of my routes.js, in my /login POST, req.user works as it should.
'use strict'
var User = require('mongoose').model('User')
module.exports = function(app, passport){
console.log('passport', passport)
app.route('/')
.get(function(req, res){
res.render('index')
})
app.get('/signUp', function(req, res){
res.render('signup')
})
app.route('/user')
.get(function(req, res){
})
.post(passport.authenticate('local-signup', { successRedirect: '/',
failureRedirect: 'signup' }))
app.route('/login')
.get(function(req, res){
res.render('login')
})
.post(passport.authenticate('local-login', { successRedirect: '/',
failureRedirect: '/login'}), function(req, res){
/* *** LINE 27 *** */ console.log('req.user', req.user)
})
app.route('/profile')
.get(function(req, res){
/* *** LINE 33 *** */ console.log('req.user', req.user)
if(!req.user){
res.render('profile', {user: "You're not logged in"})
}
if(req.user){
res.render('profile', {user: req.user})
}
})
}
Why isn't req.user defined in all my routes? Shouldn't express session populate a persisting req.user object?
Any help appreciated. Thanks!
You should define isLoginedIn funtion in routes.js as follow:
// route middleware to ensure user is logged in
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/');
}
Then replace:
app.route('/profile')
.get(function(req, res){
console.log('req.user', req.user)
if(!req.user){
res.render('profile', {user: "You're not logged in"})
}
if(req.user){
res.render('profile', {user: req.user})
}
})
by:
// PROFILE SECTION =========================
app.get('/profile', isLoggedIn, function(req, res) {
res.render('profile.ejs', {
user : req.user
});
});

Categories