向Mean.io初学者解释Mean.io示例包的身份validation是如何工作的

我从本教程video中学习了mean.io ,它显示了示例包(由myModule包创build,也在文档的 “包”中进行了描述)。 我想帮助理解给定的authentication/授权如何工作。

默认样本包/模块在客户端具有简单的用户authentication

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

不同身份validation的神奇依赖于app.get()的第二个参数和其他身份validationcallback :none, auth.requiresLoginauth.requiresAdmin

这是authentication魔术(也在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 /包/访问/服务器/configuration/ passport.jsexportsmodule.exports = function(passport) { ...} , github ? 如果是这样,我们可以在什么情况下使用这个“出口”?


由于authentication的授权规则是在包“access”中编写的,并在“mymodule”包中使用,所以Mean.io包不是彼此独立的。 Access包已注册

myapp / packages / access / app.js , github :

 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会自动链接所有的软件包,还是有代码将软件包链接到某处? 是否由于“这是为了向后兼容”部分所示的链接? 如果是这样,哪里可以使用“授权”? 所有的软件包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”,会发生什么?

关于问题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 foo= FOO ; bar= BAR

例如,请参阅Node的模块文档或者requireexports

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

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

有代码来“链接”软件包。 这是require声明。

在你的app.js源代码中,第一行(阅读var mean = require('meanio') )将设置局部variables的mean ,无论分配给exports对象的是什么时候meanio.js和/或meanio模块被加载。

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

关于问题C

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

在这种情况下:

1) var mean = require('meanio')在第1行中input“meanio”模块,使得局部variablesmean或多或less被设置为等于在输出模块中的exports值。

2) Module = mean.Module in line 2设置局部variablesModule等于mean.Module的值,该值必须在meanio模块中分配。

3) var Access = new Module('access')正在实例化Module类的一个实例,并将其赋值给本地variablesAccess

4) Access.passport = passport在名为Accessmeanio.Module的实例内分配名为passport的实例variables(对于passport模块的值,在第3行上require d)

5) Access.middleware = auth在名为Accessmeanio.Module的实例内(指向第11行的require('./server/config/authorization')返回的值)分配名为middleward的实例variables。

我不熟悉“meanio”模块,但是基于这个代码,它看起来像是通过分配特定的“魔术”variables名来configurationmeanio.Module("access")实例(名为Access )。

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

也就是说,“meanio”模块的作者似乎决定使用特殊的variables名称来configuration类,而不是传递给构造函数的“setter”方法或参数。 我假设在有意义的代码中的某处你会发现一个类似this.middlewarethis.passport ,代码假设你已经“填充”了那些实例variables,就像你的代码示例的最后几行。

如果您要添加Access.auth = auth那么所有可能发生的情况是, Access对象将具有名为auth的新属性,其等于本地variablesauth

如果您使用Access.auth 而不是 Access.middleware ,则假定Access类中使用this.middleware任何代码this.middleware将失败,因为没有赋值给Access.middlewareAccess.auth也不是“魔术“有意义的variables名正在寻找。