Authentication returns "401 (unauthorized)" when it should not

This is the first time I set up the authentication features and get unexpected results after a user logs in. A colleague gave me an application with working authentication to model my application after, and it seems to me that everything I have done is correct.

I use AngularJS in the interface, the back-end framework SailsJS and PassportJS authentication middleware.

My source (for now) is stored publicly ... the backend API is here on Github ( the Github API ) and the front-end code is here ( Front-End Github )

What basically happens is that the user

  • Holds down the login button that launches this function

    login: function (credentials) { return baseAuth.customPOST(credentials, 'login').then(function (user) { $log.debug('User logged in: ', user); isAuthenticated = true; return user; }); }, 
  • The controller logic for this customPOST is

     login: function (req, res, next) { passport.authenticate('local', function (err, user, info) { if (err) { return res.json(err); } else if (user) { req.logIn(user, function (err) { if (err) { return res.json(err); } return res.json(user); }); } else { return res.json(400, info); } })(req, res); }, 
  • At this stage, the passport must do its job and log into the user’s system

     passport.use(new LocalStrategy({ usernameField: 'email', passwordField: 'password' }, function(email, password, next) { User.findOne({ email: email }) .exec(function (err, user) { if (err) { return next(err); } if (user) { if (user.activated) { bcrypt.compare(password, user.password, function (err, valid) { if (err) { next(err); } if (valid) { return next(null, user, { message: 'Logged In' }); } else { return next(null, false, { message: 'Incorrect password'}); } }); } else { next(null, false, { message: 'User is not activated. Please contact admins.'}); } } else { next(null, false, { message: 'Could not find user with email ' + email }); } }); } )); 

In the console, I always get this to be successful.

The console reads:

 User logged in: Object {firstName: "John", lastName: "Doe", email: " john_doe@work.com ", activated: true, isUser: true…} 
  1. Then my understanding of what is happening becomes fuzzy. I know that the application then tries to check if the user is authenticated. IsAuthenticated starts up, which looks like in AngularJS:

     isAuthenticated: function (force) { var deferred = $q.defer(); if (isAuthenticated && currentUser) { deferred.resolve(currentUser); } else { return baseAuth.customGET('authenticated').then(function (user) { deferred.resolve(currentUser); isAuthenticated = true; currentUser = user; return user; }); } return deferred.promise; } 
  2. It affects this action in the UserController backend.

     isAuthenticated: function (req, res) { if (req.isAuthenticated() && req.user.isUser) { return res.json(req.user); } else { return res.send(401); } }, 

Then it fails :( GET http://localhost:1337/user/authenticated 401 (Unauthorized) Neither req.isAuthenticated nor req.user.isUser pass. I separated them for individual testing, and none of them are true . "isUser" is the value that I defaults to true, and therefore this should be true for every single user in db. req.isAuthenticated also fails, which I don't quite understand.

Does anyone have an understanding of my problem? What have I done, have I done wrong?

+6
source share
3 answers

If your external application is of a different origin than your backend application, AJAX requests will not contain a session cookie , and req.isAuthenticated() will never return true.

Use the withCredentials options to force it.

 $http({ withCredentials: true, ... }) 

Restangular seems to use the same options:

https://github.com/mgonto/restangular#setdefaulthttpfields

https://docs.angularjs.org/api/ng/service/$http#usage

Edit: you should also check the server side configuration as indicated by idbehold


As suggested by Matan, you really should try to create a server-side password generation generator.

https://github.com/sails101/even-more-passport

https://github.com/kasperisager/sails-generate-auth

+3
source

Usually, error 401 “Unauthorized” actually refers to a credential error, and not to error 403, which refers to a real Unauthorized error (forbidden), so you must first check your client with Postman to check it, and then go to to the customer.

although I would strongly recommend that you give up this github project and use this tutorial to implement your passport.js authentication as you only need to execute 2 lines of code and some configurations and not get confused with the code: https: //www.bearfruit .org / 2014/07/21 / tutorial-easy-authentication-for-sails-js-apps /

+2
source

Since passport.js works using the basic concept of strategies, you need to make sure that you authenticate using the correct one. I don’t see a strategy called "user" anywhere

 passport.use(new LocalStrategy({ usernameField: 'email', passwordField: 'password' }, function(email, password, next) { User.findOne({ email: email }) .exec(function (err, user) { if (err) { return next(err); } if (user) { if (user.activated) { bcrypt.compare(password, user.password, function (err, valid) { if (err) { next(err); } if (valid) { return next(null, user, { message: 'Logged In' }); } else { return next(null, false, { message: 'Incorrect password'}); } }); } else { next(null, false, { message: 'User is not activated. Please contact admins.'}); } } else { next(null, false, { message: 'Could not find user with email ' + email }); } }); } )); 

should be changed to

 passport.use('user', new LocalStrategy({ usernameField: 'email', passwordField: 'password' }, function(email, password, next) { User.findOne({ email: email }) .exec(function (err, user) { if (err) { return next(err); } if (user) { if (user.activated) { bcrypt.compare(password, user.password, function (err, valid) { if (err) { next(err); } if (valid) { return next(null, user, { message: 'Logged In' }); } else { return next(null, false, { message: 'Incorrect password'}); } }); } else { next(null, false, { message: 'User is not activated. Please contact admins.'}); } } else { next(null, false, { message: 'Could not find user with email ' + email }); } }); } )); 

Also make sure your isUser user isUser set to true.

+2
source

Source: https://habr.com/ru/post/989840/


All Articles