向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.requiresLogin
或auth.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.js的exports
: module.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的模块文档或者require
和exports
。
关于问题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
在名为Access
的meanio.Module
的实例内分配名为passport
的实例variables(对于passport
模块的值,在第3行上require
d)
5) Access.middleware = auth
在名为Access
的meanio.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.middleware
和this.passport
,代码假设你已经“填充”了那些实例variables,就像你的代码示例的最后几行。
如果您要添加Access.auth = auth
那么所有可能发生的情况是, Access
对象将具有名为auth
的新属性,其值等于本地variablesauth
。
如果您使用Access.auth
而不是 Access.middleware
,则假定Access
类中使用this.middleware
任何代码this.middleware
将失败,因为没有赋值给Access.middleware
, Access.auth
也不是“魔术“有意义的variables名正在寻找。