AngularJS passportJS用户在页面重新加载后注销

时间:2016-02-13 10:31:56

标签: angularjs authentication passport.js mean-stack

我按照Chirp MEAN堆栈教程将passportJS身份验证添加到我的网站(https://github.com/hwz/chirp)。

登录和注册工作正常(MongoDB中的护照,商店和查找用户),只要我留在单页应用程序中。 如果我在浏览器中单击刷新/重新加载,则用户似乎不再登录。

重新加载后有人知道如何选择页面的会话/用户吗? 我现在挣扎了好几天,在网上找不到任何东西。非常感谢每一个帮助。

如果用户未登录,则网站的菜单会要求登录/注册。

如果用户已登录,则菜单会显示用户下拉菜单。

在Angular中,我使用以下代码作为页面菜单:

<a ui-sref="signin" class="btn btn-success" role="button" ng-hide="authenticated">Login</a>
<a ui-sref="register" class="btn btn-primary" role="button" ng-hide="authenticated">Register</a>

<span class="dropdown" ng-show="authenticated">
  <button class="btn btn-success dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
     {{current_user}}
    <span class="caret"></span>
  </button>
  <ul class="dropdown-menu" aria-labelledby="usermenu">
    <li><a ui-sref="#" ng-click="signout()">Logout</a></li>
  </ul>
</span>

页面重新加载ng-show =“authenticated”再次为false。 创建了一个connect.sid cookie,并在页面重新加载后仍然存在。但似乎没有考虑到。

AngularApp.js看起来像:

var app = angular.module('myApp', ['ui.router']);
...
app.run(function($rootScope, $http) 
{
  $rootScope.authenticated = false;
  $rootScope.current_user = '';

  $rootScope.signout = function()
  {
      $http.get('auth/logout');
      $rootScope.authenticated = false;
      $rootScope.current_user = '';
  };
});

我的猜测是,我必须在这里添加代码吗?

AuthenticationController.js看起来像:

var app = angular.module('myApp');

app.controller('authController', function($scope, $http, $rootScope, $location)
{
  $scope.user = {username: '', password: ''};
  $scope.error_message = '';

  $scope.login = function()
  {
    $http.post('/auth/login', $scope.user).success(function(data)
    {
      if(data.state == 'success')
      {
        $rootScope.authenticated = true;
        $rootScope.current_user = data.user.username;
        $location.path('/');
      }
      else
      {
        $scope.error_message = data.message;
      }
    });
  };

  $scope.register = function(){
    $http.post('/auth/register', $scope.user).success(function(data)
    {
      if(data.state == 'success')
      {
        $rootScope.authenticated = true;
        $rootScope.current_user = data.user.username;
        $location.path('/');
      }
      else
      {
        $scope.error_message = data.message;
      }
    });
  };
});

Server.js看起来像:

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var passport = require('passport');

var api = require('./routes/api');

var app = express();
//initialize mongoose schemas
require('./models/models');
var mongoose = require('mongoose');                         //add for Mongo support
mongoose.connect('mongodb://localhost/myApp');  //connect to Mongo

app.set('port', process.env.PORT || 3000);

//Middleware
app.use(logger('dev'));
app.use(session({ secret: 'changedforstackoverflow', rolling: true, resave: true, saveUninitialized: false }));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(__dirname + '/../frontend'));     //serve static assets
app.use(passport.initialize());
app.use(passport.session());

//// Initialize Passport
var initPassport = require('./passport-init');
initPassport(passport);

var authenticate = require('./routes/authenticate')(passport);

app.use('/api', api);
app.use('/auth', authenticate);
...

如果有帮助,我可以发布更多代码。但据我所知,后端的身份验证工作正常。重新加载后只有Angular没有从cookie中获取会话,对吗?

1 个答案:

答案 0 :(得分:2)

确定。我终于成功了。

据我所知,护照本身就是关注会话和cookie。我也无法从cookie中读取数据,因为它受到了HTMLonly attibute的保护。

那么,该怎么办? 我在后端添加了控制台日志,以查看重新加载请求是否仍然是后端端的有效用户。

我在:

之后直接添加到server.js(后端/节点)
app.use('/auth', authenticate):

这样:

app.use(function (req, res, next) {
  console.log(req.isAuthenticated());
  console.log(req.user);
  next();
});

现在我在服务器控制台中看到,重新加载页面后的每个请求仍然是一个有效的用户,但angular不知道它。

我在上一篇文章中放入一些代码的地方是正确的。 App.run必须从后端获取用户数据!

所以我添加了这个函数(frontend / angular):

app.run(function($rootScope, $http, $location) 
{
  $rootScope.loggedIn = function()
  {
    $http.post('/auth/isloggedIn').success(function(data)
    {
      if(data.state == 'success')
      {
        $rootScope.authenticated = true;
        $rootScope.current_user = data.user.username;
        $location.path('/');
      }
      else
      {
        $rootScope.authenticated = false;
        $rootScope.current_user = '';
        $location.path('/');
      }
    });
  };

  $rootScope.loggedIn();

现在我们确实需要构建一个函数,当用户在后端登录时返回用户数据。我们在上面的loggedIn函数中调用的url需要做一些事情。所以我把它添加到了身份验证路由器(后端/节点):

//is logged in
router.post('/isloggedin', function(req, res){
    if(req.isAuthenticated())
    {
        res.send({state: 'success', user: req.user});
    }
    else
    {
        res.send({state: 'failure', user: null});
    }
});

最后一步是验证它是否适用于多个用户,因此我使用了两个浏览器并使用不同的用户登录并刷新了页面。两个用户都正确识别并自动登录&#34;。

万岁! ; - )