使用 Express/Passport、AngularJS 和 EnsureLoggedIn 进行身份验证和路由不适用于“/”url

twi*_*inb 5 node.js express angularjs angular-ui-router passport.js

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

EnsureLoggedIn 的存储库在这里

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

如果我没有登录,在登录屏幕上,我将“/login”修改为“/”或“”,我会被发送到 AngularJS 中的“main”并被视为已登录(我假设是因为它识别会话?)并能够单击“/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');
    });
};
Run Code Online (Sandbox Code Playgroud)

我也尝试过以下路线:

app.route('/*').get(function(req, res) {
    res.sendfile(app.get('appPath') + '/index.html');
});
Run Code Online (Sandbox Code Playgroud)

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

这是我在 Angular 端的路由片段,它使用 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'
Run Code Online (Sandbox Code Playgroud)

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

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

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

编辑:

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

app.route('/')
    .get(function(req, res) {
        res.render('login');
    });
Run Code Online (Sandbox Code Playgroud)

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

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

Dre*_*ker 0

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

 $routeProvider
    .when("/login", { templateUrl: "/view/account/login.html", controller: Login })
    .when("/forgottenpassword", { templateUrl: "/view/account/forgottenpassword.html", controller: ForgottenPassword })
    .otherwise({ redirectTo: "login" });
Run Code Online (Sandbox Code Playgroud)

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

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

Angular 中提供的原始 $routeProvider 还需要一个公共方法来在添加新路由之前清除现有路由。

  var routes = {};
Run Code Online (Sandbox Code Playgroud)

添加

  this.ClearRoutes = function ()
  {
      routes = {};
  }
Run Code Online (Sandbox Code Playgroud)

登录成功后的使用示例

$routeProvider.ClearRoutes();

$routeProvider
    .when("/home", { templateUrl: "/view/home.html", controller: Home })
    .when("/logoff", { templateUrl: "/view/account/logoff.html", controller: Logoff })
    .otherwise({ redirectTo: "home" });
Run Code Online (Sandbox Code Playgroud)