I am building an application using node.js and express.js with passport authentication using MVC Architecture. I have strictly followed a tutorial on how to implement and integrate passport authentication using a local strategy. It seems like the strategy is working fine. In my controller which is handling the authentication (using passport.authenticate), successRedirect is always executed given that I submit matching details with an instance in the database. However, after redirecting to wherever successRedirect points to, I am getting a GET request Error 500. Afterwards, if I try to access other routes, I still get the same error, thus failing to display the desired view template. However, if I try to access the same routes without attempting to login, the GET request executes successfully with statusCode 200.
The exact error I get is :
GET /dashboard 500 4.313 ms - 941
users.js route
var usersController = require('../../controllers/usersController');
/* POST login */
router.post('/login', usersController.loginAccount);
usersController.js
module.exports.loginAccount = function (req, res, next) {
passport.authenticate('local', {
successRedirect: 'dashboard',
failureRedirect: '/users/login',
failureFlash: true
}) (req, res, next);
}
index.js route
router.get('/dashboard', ensureAuthenticated, indexController.dashboardPage);
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated())
return next();
else{
req.flash('error_msg', 'Please log in to view this resource');
res.redirect('/users/login');
}
}
Command line after attempting login:
Executing (default): SELECT id, firstname, lastname, email, username, password, address, createdAt, updatedAt FROM clients AS client WHERE client.username = 'nikolaisennn' LIMIT 1;
Serializing user
POST /users/login 302 144.266 ms - 74
Deserializing user
User ID: 65
GET /dashboard 500 4.313 ms - 941
I have been stuck on this issue for a while, tried to find solutions online but I haven't really managed to find what I need. I am sure that there is something small that I am missing, yet I have no clue what it is.
Related
I attempted to login to my application which utilizes the Google OAuth flow. I have successfully logged in to this application in the past by going to
localhost:5000/auth/google
When I select my email, the process just hangs for about a minute and then I get the:
TokenError: Code was already redeemed.
which occurs at localhost:5000/auth/google/callback, which I thought perhaps that would not be a problem because it is a route that is in my authRoutes.js file below:
const passport = require('passport');
module.exports = (app) => {
app.get(
'/auth/google',
passport.authenticate('google', {
scope: ['profile', 'email']
})
);
app.get('/auth/google/callback', passport.authenticate('google'));
app.get('/api/logout', (req, res) => {
req.logout();
// prove to whoever is
// making request that
// they are no longer signed in
res.send(req.user);
});
app.get('/api/current_user', (req, res) => {
res.send(req.user);
});
};
I thought I would check by going to localhost:5000/api/current_user which should be rendering the googleID and _id of the user as an object, but instead I get a blank screen which means I am not successfully logged in.
I am not sure what is going on here.
When you are attempting to go through the Google OAuth flow in your local application and it just hangs, that is not a problem. Your issue was that you did not have your MongoDB database running, so it was difficult for your application to verify if this was a new user or an old user logging in based off whats stored in the database.
I'm creating a simple PWA to draw in multiple data sources into one application. I'm currently trying to set up authentication using a combination of passport and the twitter-strategy.
After the user has successfully authenticated they're account, twitter redirects to the callback endpoint, with the valid user data.... essentially the auth has been successful. However, when sending the user back to the client side application a html document with the word null is presented, rather than the application.
With the following code, I expect:
Twitter to return to callback URL
Server to perform actions in authSuccess function
Redirect to the provided url on the client
routes.js to server the application shell via the catch all route
Client application to boot and handle the URL served
Currently, only the first two steps are successful, and the app simply displays null (with the correct url in the address bar), rather than the expected output. Changing the location of the writeHead() call to / works, and the user is authenticated as expected ().
routes.js
let users = require('../controllers/userController');
app.get('/user/auth/twitter/callback',
passport.authenticate('twitter', {
failWithError: true
}),
function(req, res) {
console.log('[Twitter] Auth success route hit');
users.authSuccess(req, res);
},
function(err, req, res, next) {
console.log('[Twitter] Auth failure route hit');
users.authFailure(err, req, res, next);
}
);
app.get('*', function(req, res){
console.log('[Route] Catch All: ' + req.path);
res.sendFile(path.resolve(__dirname, '../../public/index.html'));
});
userController.js
authSuccess(req, res) {
console.log('[User Controller] User',req.user);
// Set some cookies here
res.writeHead(302, {'Location': '/user/profile'});
// res.redirect('/user/profile');
res.end();
}
Any help much appreciated. If you need more code, just ask :)
Thanks
I have a problem with sessions in my app. I'm trying to learn Passport.js based on this tutorial: http://www.sitepoint.com/local-authentication-using-passport-node-js/ . What I want to do is to allow the acccess for only authenticated users. The process of login works great, but when I check if the user is authenticated, it always says not. What could go wrong?
Here is the checking function:
if (req.isAuthenticated()) {
return next();
else {
res.redirect('/');
}
Here is the path from the router:
router.get('/secret', isAuthenticated, function(req, res) {
res.send('Welcome to the secret page');
});
I didn't find any domunentation about how to check if the session was established, where it is and so on.
Try this, taken from passport.js documentation.
app.get('/secret', passport.authenticate('local'), function(req, res) {
// If this function gets called, authentication was successful.
// `req.user` contains the authenticated user.
});
http://passportjs.org/guide/authenticate/
Hi Guys I'm learning node.js with expressjs framework. Now I want create a simple site with two page(login page and logged page). With this exercise my main goal is to authorized only the logged user to see the logged page.
I want prevent that a user not registered can see the logged page using www.mysite.com/logged
So in app.js I have added this
app.get('/logged', routes.logged);
Then in index.js(that it's located in ./routes folder) I have wrote this
exports.logged = function(req, res) {
if(req.session.isLogged) {
res.status(200);
res.render('logged', {Title: req.session.name});
} else {
res.status(403);
res.render('403');
}
}
But when I try to access to the logged page via www.example.com/logged I always get 500 Error Internal server error
The error that I receive is this:
Express
500 Error: Failed to lookup view "TypeError: Cannot read property 'commonUserId' of undefined" in views directory "C:\Users\Fabio\Desktop\SitoStatistica\views"
at Function.app.render (C:\Users\Fabio\Desktop\SitoStatistica\node_modules\express\lib\application.js:493:17)
at ServerResponse.res.render (C:\Users\Fabio\Desktop\SitoStatistica\node_modules\express\lib\response.js:798:7)
at Object.handle (C:\Users\Fabio\Desktop\SitoStatistica\app.js:32:6)
at next (C:\Users\Fabio\Desktop\SitoStatistica\node_modules\express\node_modules\connect\lib\proto.js:188:17)
at next (C:\Users\Fabio\Desktop\SitoStatistica\node_modules\express\node_modules\connect\lib\proto.js:190:11)
at next (C:\Users\Fabio\Desktop\SitoStatistica\node_modules\express\node_modules\connect\lib\proto.js:190:11)
at pass (C:\Users\Fabio\Desktop\SitoStatistica\node_modules\express\lib\router\index.js:110:24)
at nextRoute (C:\Users\Fabio\Desktop\SitoStatistica\node_modules\express\lib\router\index.js:100:7)
at callbacks (C:\Users\Fabio\Desktop\SitoStatistica\node_modules\express\lib\router\index.js:167:11)
at callbacks (C:\Users\Fabio\Desktop\SitoStatistica\node_modules\express\lib\router\index.js:170:9)
#pero
Implementing your own authentication system is not a good ideal.
For NodeJS authentication, you should take a look at PassportJS
Authentication then turn out to be very simple:
app.post('/login', passport.authenticate('local', { successRedirect: '/',
failureRedirect: '/login' }));
then
app.get('/logged', function (req, res, next) {
if (req.isAuthenticated()) {
return res.redirect('/login');
}
return res.render('login');
});
Users visiting http://localhost/login are instantly redirected to Facebook for confirmation of application usage. Once authorized, Facebook contacts http://localhost/login?code= with a special code that allows the server to obtain the user's information such as their name and gender.
Express().get('/login', Passport().authenticate('facebook', {
failureRedirect: 'http://localhost/',
}), function(req, res) {
database.saveData(req.user, **randomlyGeneratedHash**);
res.cookie('session', **randomlyGeneratedHash**);
res.end();
});
This works as expected, but when authenticated users visit the /login in succession, the whole process is repeated and they get a new cookie.
Is there a way that I can run some code inbetween Express and Passport, to stop Passport from redirecting to Facebook if the user has a valid cookie already?
You can use something similar to ensureAuthenticated on your /login route:
var CheckIfAlreadyLoggedIn = function(req, res, next) {
if (req.isAuthenticated()) {
return res.redirect('/'); // or where you want them to go
}
next();
};
Express().get('/login', CheckIfAlreadyLoggedIn, Passport().authenticate('facebook', ...));
This would redirect users that are already logged in back to / when they try to access /login.