如何在 meanjs 中复制管理仪表板以创建用户目录

How do I replicate the admin dashboard in meanjs to create a user directory

我是 meanjs 的新手,但我目前正在尝试创建一个简单的应用程序,用户可以在其中相互连接。

现在我只想实现一个功能,用户可以通过搜索互相查找,除了我将 运行 保持在 403 错误之外。我试图通过复制构成管理 'manage users' 视图的文档来修复它。

我不想给每个人 'admin' 角色,所以我为用户添加了一个新策略,他们只被授予 'get' 权限。我还为普通用户添加了一个新的路由、视图和控制器,这些是从管理文件修改而来的。

它运行良好,但我仍然无法让系统在以非管理员角色登录时允许访问新的 userDirectory 视图。我认为它与 auth.interceptor.client.service.js 文件和 modules/core/client/app/init.js 文件以及我制作的新文件提供的 $state 有关,但我试图修改它们但它仍然在抛出我的应用程序正文中的 /forbidden 视图。

我不知道还能做什么。任何帮助将不胜感激。

该应用以 home.client.view.html 视图开头:

<section ng-controller="HomeController">

  </div>
  <div class="jumbotron text-center" ng-hide="authentication.user">
    <div class="row">
      <div class="col-md-6 col-md-offset-3 col-sm-6 col-sm-offset-3 col-xs-12">
        <img alt="MEAN.JS" class="img-responsive text-center" src="modules/core/client/img/brand/Logo.png" />
      </div>
    </div>
    <br>
    <div class="row">
      <p class="lead">
        An app
      </p>
    </div>
    <div class="row">
      <p>
        <!-- <a class="btn btn-primary btn-lg" href="http://meanjs.org" target="_blank">Learn more</a> -->
      </p>
    </div>
  </div>
  <div ng-if="authentication.user">
    <h2>Congratulations! You are logged in.</h2>
    <div ng-include="'/modules/users/client/views/user/user-directory.client.view.html'"></div>
    <!-- <div ng-include="'/api/users'"></div> -->

  </div>

</section>

这是我对 userDirectory 的看法(修改自 modules/users/client/views/admin/list-users。client.view.html):

<section ng-controller="UserDirectoryController">
  <div class="page-header">
    <div class="row">
      <div class="col-md-4">
        <h1>Users</h1>
      </div>
      <div class="col-md-4" style="margin-top: 2em">
        <input class="form-control col-md-4" type="text" ng-model="search" placeholder="Search" ng-change="figureOutItemsToDisplay()" />
      </div>
    </div>
  </div>
  <div class="list-group">
    <a ng-repeat="user in pagedSearchItems" ui-sref="users.user({userId: user._id})" class="list-group-item">
      <h4 class="list-group-item-heading" ng-bind="user.username"></h4>
      <p class="list-group-item-text" ng-bind="user.email"></p>
    </a>
  </div>

  <pagination boundary-links="true" max-size="8" items-per-page="itemsPerPage" total-items="filterLength" ng-model="currentPage" ng-change="pageChanged()"></pagination>
</section>

我的控制器(修改自modules/users/client/controllers/admin/list-users。client.controller.js):

'use strict';

angular.module('users.user').controller('UserDirectoryController', ['$scope', '$filter', 'User',
  function ($scope, $filter, User) {
    User.query(function (data) {
      $scope.users = data;
      $scope.buildPager();
    });

    $scope.buildPager = function () {
      $scope.pagedSearchItems = [];
      $scope.itemsPerPage = 15;
      $scope.currentPage = 1;
      $scope.figureOutItemsToDisplay();
    };

    $scope.figureOutItemsToDisplay = function () {
      $scope.filteredItems = $filter('filter')($scope.users, {
        $: $scope.search
      });
      $scope.filterLength = $scope.filteredItems.length;
      var begin = (($scope.currentPage - 1) * $scope.itemsPerPage);
      var end = begin + $scope.itemsPerPage;
      $scope.pagedSearchItems = $scope.filteredItems.slice(begin, end);
    };

    $scope.pageChanged = function () {
      $scope.figureOutItemsToDisplay();
    };
  }
]);

我的服务(修改自modules/users/client/services/users.client.service.js):

'use strict';

// Users service used for communicating with the users REST endpoint
angular.module('users').factory('User', ['$resource',
  function ($resource) {
    return $resource('api/userDirectory', {}, {
      update: {
        method: 'PUT'
      }
    });
  }
]);

//TODO this should be Users service
angular.module('users.user').factory('User', ['$resource',
  function ($resource) {
    return $resource('api/userDirectory/:userId', {
      userId: '@_id'
    }, {
      update: {
        method: 'PUT'
      }
    });
  }
]);

angular.module('users.user').factory('User', ['$resource',
  function ($resource) {
    return $resource('api/userDirectory/:userId', {
      userId: '@_id'
    }, {
      update: {
        method: 'PUT'
      }
    });
  }
]);

我的新route.js(修改自modules/users/server/routes/admin。server.routes.js):

'use strict';

/**
 * Module dependencies.
 */
var userPolicy = require('../policies/userDirectory.server.policy'),
  userDirectory = require('../controllers/userDirectory.server.controller');

module.exports = function (app) {
  // User route registration first. Ref: #713
  require('./users.server.routes.js')(app);

  // Users collection routes
  app.route('/api/userDirectory')
    .get(userPolicy.isAllowed, userDirectory.list);

  //Single user routes
  app.route('/api/userDirectory/:userId')
    .get(userPolicy.isAllowed, userDirectory.read);

  // Finish by binding the user middleware
  app.param('userId', userDirectory.userByID);
};

最后是我的 userDirectory 新策略(修改自 modules/users/server/policies/admin。server.policy.js):

'use strict';

/**
 * Module dependencies.
 */
var acl = require('acl');

// Using the memory backend
acl = new acl(new acl.memoryBackend());

/**
 * Invoke User Permissions
 */
exports.invokeRolesPolicies = function () {
  acl.allow([{
    roles: ['user'],
    allows: [{
      resources: '/api/userDirectory',
      permissions: ['post', 'get']
    }, {
      resources: '/api/userDirectory/:userId',
      permissions: ['post', 'get']
    }]
  }]);
};

/**
 * Check If User Policy Allows
 */
exports.isAllowed = function (req, res, next) {
  var roles = (req.user) ? req.user.roles : ['guest'];

// Check for user roles
  acl.areAnyRolesAllowed(roles, req.route.path, req.method.toLowerCase(), function (err, isAllowed) {
    if (err) {
      // An authorization error occurred.
      return res.status(500).send('Unexpected authorization error');
    } else {
      if (isAllowed) {
        // Access granted! Invoke next middleware
        return next();
      } else {
        return res.status(403).json({
          message: 'User is not authorized'
        });
      }
    }
  });
};

我认为最简单的方法是向只有用户可以访问的服务器添加一个新路由,并创建一个服务来检索该数据。

(这只是一个从数据库获取数据的服务,你可以在任何view/controller中使用它,或者创建一个只有users/admins可以访问的新视图)

在您的模块(客户端)中创建一个服务以向服务器执行 http post/get:

(function() {
 'use strict';
 angular
   .module('yourModule')
   .factory('UserListService', function($http) {
     var routes = {};
     routes.getUserList = function(username) {
       return $http.post('/api/userlist', username); //you can do a 'post' to search for one username or just 'get' to see all users.
     };
     return routes;
   }
 );
})();

然后在modulses/yourModule/server/routes中添加路由:

app.route('/api/userlist').all(yourModulePolicy.isAllowed)
.post(yourModule.getUserList); //get or post its up to you

不要忘记在 modulses/yourModule/server/policies

中添加权限
roles: ['user'],
allows: [{
  resources: '/api/userlist',
  permissions: ['post'] //get or post
}]

然后在modulses/yourModule/server/controllers

中处理请求
exports.getUserList = function(req, res) {
  var name_to_search = req.body.username;
  //here you can query the database for all users or the name you
  //received in the post.
  //NOTE: if you query the user DB there can be sensitive information
  //such as the hashed password etc, make sure you delete that here
  //before you respond with the user/user list
  res.jsonp(user_list);
};

之后,您可以像这样在客户端控制器中使用用户信息:

UserListService.getUserList({
   username: 'john'
 }).then(function(data) {
   vm.userlist = data.data;
 });

确保将 UserListService 注入控制器并将其传递给控制器​​函数:

YourController.$inject = ['UserListService'];

function YourController(UserListService){...}

希望这有帮助,我也是整个平均堆栈的新手,甚至不知道这是否是最佳解决方案,但它会起作用。

编辑:

当您使用控制器在客户端创建新视图时,您需要将其添加到 modules/yourModule/client/config/yourModule.client.routes.js

中的客户端路由
.state('your.state', {
        url: '-yourUrl',
        templateUrl: 'modules/yourModule/client/views/user-list.client.view.html',
        controller: 'YourController',
        controllerAs: 'vm',
        data: {
          roles: ['user', 'admin'],
          pageTitle: 'User List'
        }
      })