9

我正在从本教程视频中学习mean.io,它显示了示例包(由 . 创建。它也在文档的“包”下进行了描述)。我想帮助理解给定的身份验证/授权是如何工作的。mean package mymodule

默认示例包/模块在客户端具有简单的用户身份验证

myapp/packages/mymodule/public/views/index.html包含:

    <li>
      <a href="mymodule/example/anyone">Server route that anyone can access</a>
    </li>
    <li>
      <a href="mymodule/example/auth">Server route that requires authentication</a>
    </li>
    <li>
      <a href="mymodule/example/admin">Server route that requires admin user</a>
    </li>

在服务器端,

myapp/packages/mymodule/server/routes/mymodule.js,包含:

// The Package is past automatically as first parameter
module.exports = function(Mymodule, app, auth, database) {

  app.get('/mymodule/example/anyone', function(req, res, next) {
    res.send('Anyone can access this');
  });

  app.get('/mymodule/example/auth', auth.requiresLogin, function(req, res, next) {
    res.send('Only authenticated users can access this');
  });

  app.get('/mymodule/example/admin', auth.requiresAdmin, function(req, res, next) {
    res.send('Only users with Admin role can access this');
  });

  ...
};

不同身份验证的魔力依赖于app.get()带有附加身份验证回调的第二个参数:无auth.requiresLogin、或auth.requiresAdmin

这是身份验证魔法(也在github 上):

myapp/packages/access/server/config/authorization.js

/**
 * Generic require login routing middleware
 */
exports.requiresLogin = function(req, res, next) {
  if (!req.isAuthenticated()) {
    return res.send(401, 'User is not authorized');
  }
  next();
};

/**
 * Generic require Admin routing middleware
 * Basic Role checking - future release with full permission system
 */
exports.requiresAdmin = function(req, res, next) {
  if (!req.isAuthenticated() || !req.user.hasRole('admin')) {
    return res.send(401, 'User is not authorized');
  }
  next();
};

问题 A:为什么在 authorization.js 中是“exports.requiresLogin”和“exports.requiresAdmin”而不是“somethingelse.requiresLogin”和“somethingelse.requiresAdmin”? 这是与myapp/packages/access/server/config/passport.jsexports: module.exports = function(passport) { ...}github相关的“导出”吗?如果是这样,在什么情况下我们可以使用这个“出口”?


由于身份验证的授权规则写在包“access”中并在包“mymodule”中使用,Mean.io 包之间不是相互独立的。Access包裹注册于

myapp/packages/access/app.jsgithub

var mean = require('meanio'),
  Module = mean.Module,
  passport = require('passport');

var Access = new Module('access');

Access.register(function(database) {

  // Register auth dependency

  var auth = require('./server/config/authorization');
  require('./server/config/passport')(passport);

  // This is for backwards compatibility
  mean.register('auth', function() {
    return auth;
  });

  mean.register('passport', function() {
    return passport;
  });

  Access.passport = passport;
  Access.middleware = auth;

  return Access;
});

问题 B:Mean.io 是否会自动链接所有包,或者是否有代码将包链接到某个地方?它是否由于下面显示的“这是为了向后兼容”的部分而链接的?如果是这样,“auth”可以在哪里使用?所有包myapp/packages/?在 mean.io 基础应用程序目录myapp/中怎么样?

var auth = require('./server/config/authorization');

// This is for backwards compatibility
  mean.register('auth', function() {
    return auth;
  });

问题 C:为什么它是“Access.passport = passport;”,但“Access.middleware = auth;”是“中间件”?如果它是“Access.auth = auth”会发生什么?

4

1 回答 1

0

关于问题 A(关于 的使用exports

在 Node.js 中,为对象分配值exports使这些值可用于require作为源文件的代码。

例如,给定文件foo.js

exports.foo = "FOO";
exports.bar = "BAR";

和文件main.js

var foo = require('foo.js');
console.log('foo=',foo.foo,'; bar=',foo.bar);

运行node main.js将输出foo= FOO ; bar= BAR.

例如,请参阅Node 的模块文档这篇关于requireexports的文章。

关于问题 B(关于“链接”包)

这个问题的答案是对问题 A 答案的补充。

有代码可以“链接”这些包。这是require声明。

在您的app.js源代码中,第一行(读取var mean = require('meanio'))会将局部变量设置为在加载和/或加载模块 时mean分配给exports对象的任何值。meanio.jsmeanio

与 相同passport = require('passport')。在这种情况下,本地变量passport将等于护照模块中 index.js加载exports后的值。

关于问题 C

我不完全确定你在这里问什么,但让我试一试。

在这种情况下:

1)var mean = require('meanio')在第 1 行“导入”meanio 模块,使得局部变量mean或多或少地设置为等于exportsmeanio 模块中的值。

2)Module = mean.Module在第 2 行中,将局部变量设置Module为 的值mean.Module,该值必须已在 meanio 模块中分配。

3)var Access = new Module('access')实例化Module类的一个实例,将其分配给局部变量Access

4)将named实例中Access.passport = passport的实例变量named赋值(赋值给第3行的模块d的值)passportmeanio.ModuleAccesspassportrequire

5)将named实例中Access.middleware = auth的实例变量named 赋值给第11行返回的值。middlewardmeanio.ModuleAccessrequire('./server/config/authorization')

我不熟悉“meanio”模块,但基于此代码,您似乎正在通过分配特定的“魔术”变量名称 来配置meanio.Module("access")实例(命名)。Access

换句话说,而不是Access.passport = passport; Access.middleware = auth你可能有Access.setPassport(passport); Access.setMiddleware(auth)or (而不是第 5 行) var Access = new Module('access',passport,auth)

也就是说,“meanio”模块的作者似乎已经决定使用特殊的变量名来配置类,而不是“setter”方法或传递给构造函数的参数。我假设在 meanio 代码中的某处,您会找到类似this.middlewareand的引用this.passport,其中代码假设您已经“填充”了这些实例变量,就像代码示例的最后几行中发生的那样。

如果要添加Access.auth = auth,那么将发生的所有事情都是该Access对象将具有一个名为的新属性auth,其等于局部变量的值auth

如果您使用Access.auth 而不是 Access.middleware我假设Access正在使用的类中的任何代码都this.middleware将失败,因为没有任何值被分配给Access.middleware并且Access.auth不是 meanio 正在寻找的“神奇”变量名之一。

于 2016-06-03T21:34:45.680 回答