使用 Express/Passport、AngularJS 和 ensureLoggedIn 的身份验证和路由在“/”url 上不起作用

Posted

技术标签:

【中文标题】使用 Express/Passport、AngularJS 和 ensureLoggedIn 的身份验证和路由在“/”url 上不起作用【英文标题】:Authentication and Routing with Express/Passport, AngularJS and ensureLoggedIn not working on "/" url 【发布时间】:2014-09-15 06:02:52 【问题描述】:

我有一个使用 Yeoman Generator Angular Fullstack 生成器生成的 MEAN 堆栈应用程序。您应该只有通过登录才能访问该网站。

ensureLoggedIn 的 repo 是 here

注销时,如果我尝试导航到“/products”,我会被重定向到“/login”。但是,当 url 为“/”甚至“localhost:9000”时,我在重定向未登录的用户时遇到了问题,而没有斜杠。

如果我没有登录,并且在登录屏幕上,我将 '/login' 修改为只是 '/' 或 '' 我被发送到 AngularJS 中的“main”并被视为已登录(I' m 假设是因为它可以识别会话?)并且能够单击指向“/products”或“/users”的链接。

我当前的 routes.js 看起来像这样:

/**
 * Main application routes
 */

'use strict';

var errors = require('./components/errors');
var auth = require('./controllers/auth');
var passport = require('passport');
var ensureLoggedIn = require('connect-ensure-login').ensureLoggedIn;
module.exports = function(app) 

// Insert routes below
// All undefined asset or api routes should return a 404
    app.route('/:url(api|auth|components|app|bower_components|assets)/*').get(errors[404]);
    app.route('/login').get(auth.login).post(auth.loginUser);
    app.route('/logout').get(auth.logout);
    // All other routes should redirect to the index.html
    app.all('*', ensureLoggedIn('/login'));
    app.route('/*').get(function(req, res) 
        res.sendfile(app.get('appPath') + '/index.html');
    );
;

我也尝试过路线:

app.route('/*').get(function(req, res) 
    res.sendfile(app.get('appPath') + '/index.html');
);

这似乎与将 ensureLoggedIn 放在 app.all 中的行为相同。

这是我在 Angular 端的路由的 sn-p,它使用 ui-router:

.config ($stateProvider, $urlRouterProvider, $locationProvider) ->
    $httpProvider.interceptors.push('httpInterceptor')

    $urlRouterProvider
        .otherwise '/'

    $stateProvider
        .state 'main',
            url: '/'
            templateUrl: 'app/views/main/main.html'
            controller: 'MainCtrl'
        .state 'users',
            url: '/users'
            templateUrl: 'app/views/users/index.html'
            controller: 'UsersController'

正如我所说,重定向在“/users”上运行良好。我不确定这是路由问题还是身份验证问题。 Auth 应该没问题,因为单击注销确实会将您带到登录屏幕并限制访问,但不会限制对“/”路由的访问。

对于视图,login.jade 实际上是在服务器端,并在那里处理表单。除了 404.jade,所有其他视图都在客户端并使用 ui-router 提供服务。

我觉得我忽略了一些基本的东西。或者只是不完全理解这是如何协同工作的。任何帮助都会很棒。

编辑:

我尝试过的一件事是在 app.route('login') 之前更改路由:

app.route('/')
    .get(function(req, res) 
        res.render('login');
    );

并将 main 的 ui-router url 从 '/' 更改为 '/main'。

这仍然从角度抓取 index.html 并让我登录,所以它不起作用。我还尝试使用 res.redirect 登录 routes.js,但它没有重定向。

【问题讨论】:

【参考方案1】:

这是我用于处理身份验证的代码。这是一个 hack,但是当我需要对其进行编码时,我没有找到更好的方法。此外,系统中定义的路由因用户而异,因此我无法在正常配置阶段定义它们。不过,这可能有助于解决您的问题。

 $routeProvider
    .when("/login",  templateUrl: "/view/account/login.html", controller: Login )
    .when("/forgottenpassword",  templateUrl: "/view/account/forgottenpassword.html", controller: ForgottenPassword )
    .otherwise( redirectTo: "login" );

这基本上只允许访问 2 个视图。一旦有人成功验证,我将使用新的有效视图重建路由表。任何无效的导航都会转到登录视图。

我通过 hack 来做到这一点,所以它可能不是最好的 angularjs 实现。我通过在窗口对象上保留对$routeProvider 的引用来做到这一点,然后在您成功登录时正常使用$routeProvider

原来在 Angular 中提供的 $routeProvider 也需要一个公共方法来清除现有的路由,然后再添加新的路由。

之后

  var routes = ;

添加

  this.ClearRoutes = function ()
  
      routes = ;
  

成功登录后的使用示例

$routeProvider.ClearRoutes();

$routeProvider
    .when("/home",  templateUrl: "/view/home.html", controller: Home )
    .when("/logoff",  templateUrl: "/view/account/logoff.html", controller: Logoff )
    .otherwise( redirectTo: "home" );

【讨论】:

以上是关于使用 Express/Passport、AngularJS 和 ensureLoggedIn 的身份验证和路由在“/”url 上不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何在使用 Passport 进行社交身份验证后重定向到正确的客户端路由(react、react-router、express、passport)

Express + Passport.js:req.user 未定义

Express + Passport + CORS:允许多个域的会话

使用 Express/Passport、AngularJS 和 ensureLoggedIn 的身份验证和路由在“/”url 上不起作用

用户未定义:Nodejs/Express + Passport

NodeJs Express passport-jwt 从令牌中获取错误的用户