【问题标题】:AngularJS passportJS user logged out after page reloadAngularJS passportJS 用户在页面重新加载后注销
【发布时间】:2016-05-24 13:22:05
【问题描述】:

我按照 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中获取会话,对吧?

【问题讨论】:

    标签: angularjs authentication passport.js mean-stack


    【解决方案1】:

    好的。我终于成功了。

    据我所知,passport 自己负责会话和 cookie。我也无法从 cookie 中读取数据,因为它受到 HTMLonly 属性的保护。

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

    我在之后直接添加到 server.js(后端/节点):

    app.use('/auth', authenticate):
    

    这个:

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

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

    我在之前的帖子中关于放置一些代码的地方是对的。 App.run 必须从后端获取用户数据!

    所以我添加了这个功能(前端/角度):

    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});
        }
    });
    

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

    万岁! ;-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-04
      • 1970-01-01
      • 2017-08-10
      • 2018-01-17
      • 1970-01-01
      • 1970-01-01
      • 2015-10-02
      • 1970-01-01
      相关资源
      最近更新 更多