RohanArihant
RohanArihant

Reputation: 2750

how to use passport with angular node app?

I am working on a simple blog website based on angular.js + node.js and mongodb using express template. I hit with $http from angular controller by POST method to a api named users.js where login is authenticated using passport.authenticate method. I require passport-local login strategies in users.js.
But it's not working.here is angular login service code and node users api code. Can anybody tell me how can use passport.js in angular and node?

angular routing through a service

app.service('Auth',function($location,$http,$localStorage){                  
  var userLogin ;
  return{
    setLogIN:function(email,password){
      $http({
         method: 'POST',
         url: '/users/login',  //users.js having node routing.
         data: {email:email, password:password},
      })

node routing in user

router.post('/login',passport.authenticate('local', { 
    // use passport-local for authentication
    successRedirect : '/profile', 
    failureRedirect : '/login', 
    failureFlash : true 
}));

passport-local strategy

app.use(passport.initialize());

app.use(passport.session());
passport.use(new LocalStrategy(
    function (username, password, done) {

        User.findOne({username: username}, function (err, user) {

            if (err) {
                return done(err);
            }
            if (!user) {
                return done(null, false, {alert: 'Incorrect username.'});
            }
            if (user.password != password) {
                return done(null, false, {alert: 'Incorrect password.'});
            }
            return done(null, user);
        });
    }

));


passport.serializeUser(function(user, done) {
    done(null, user.id);
});

passport.deserializeUser(function(id, done) {
    User.findById(id, function(err, user) {
         done(err, user);
    });
});

function isAuthenticated(req,res,next){
    if(req.isAuthenticated())return next();
     res.redirect('/');
}

So I want to authenticate using passport, but use the client side templating/routing to keep the proper authentication.

Can someone please point me in the right direction? Or tell me if what I am doing is completely misguided?

edit : the error I AM getting with my code is it's not redirecting to profile page

TypeError: POST http://localhost:3000/users/login 500 Internal Server Error

Not a valid User

Upvotes: 10

Views: 9813

Answers (2)

RohanArihant
RohanArihant

Reputation: 2750

i found solution to my question.. how to use passport with angular-nodejs routing.......

 //angular js routing
$scope.userlogin=function(){
    $http({
        method:"post",
        url:'/users/login',
        data:{username:$scope.username,password:$scope.password},
    }).success(function(response){
        $scope.userData = response;
        $localStorage.userData = $scope.userData; 
        console.log("success!!");
        $location.path("/profile")
    }).error(function(response){
        console.log("error!!");
        $location.path("/login")
    });
}

i use POST method and hit to node (users.js) controller and get response from it. if user authentication is successful then it relocate to profile view otherwise remain on login view.

//add these two lines to app.js
// var app = express();
app.use(passport.initialize());

app.use(passport.session());

//node routing 
// add  passport-stretegies to users.js
passport.use(new LocalStrategy(function(username, password, done) {
    user.findOne({username: username }, function(err, user) {
        if (err) { return done(err); }
        if (!user) {
            return done(null, false, { message: 'Incorrect username.' });
        }
        if (user.password != password) {
            return done(null, false, { message: 'Incorrect password.' });
        }
        return done(null, user);
        // console.log(user)
    });
}));

 //passport serialize user for their session
 passport.serializeUser(function(user, done) {
     done(null, user.id);
 });
 //passport deserialize user 
 passport.deserializeUser(function(id, done) {
     user.findById(id, function(err, user) {
         done(err, user);
     });
 });

 //router on same page
 router.post('/login',passport.authenticate('local'),function(req,res){

 res.send(req.user);
     //console.log(req.user);
 });

get a hit from angular side throught post method it use passport-local method for authentication if user is authenticated seccessfully then authenticated user is sent as response..

Upvotes: 3

0xmtn
0xmtn

Reputation: 2670

By default, LocalStrategy expects dictionary parameters to be named username and password.

If you want to use email instead of username, then you should define them in your strategy:

passport.use(new LocalStrategy({
    usernameField: 'email',
    passwordField: 'password'
  },
  function(username, password, done) {
    // ...
  }
));

For your case, it should be:

passport.use(new LocalStrategy({
    usernameField: 'email',
    passwordField: 'password'
  },
function (username, password, done) {

    User.findOne({username: username}, function (err, user) {

        if (err) {
            return done(err);
        }
        if (!user) {
            return done(null, false, {alert: 'Incorrect username.'});
        }
        if (user.password != password) {
            return done(null, false, {alert: 'Incorrect password.'});
        }
        return done(null, user);
    });
}
));

Upvotes: 2

Related Questions