我从mean.io学习this tutorial video,其中显示了示例包(由mean package mymodule
创建。它也在"包"下描述docs)。我想帮助理解给定的身份验证/授权是如何工作的。
默认样本包/模块具有客户端上的简单用户身份验证
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()
与additional authentication callback的第二个参数:无,auth.requiresLogin
或auth.requiresAdmin
。
这是身份验证魔术(也在github上):
的myapp /包/访问/服务器/配置/ 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:为什么&#34; exports.requiresLogin&#34;和&#34; exports.requiresAdmin&#34;在authorization.js而不是&#34; somethingelse.requiresLogin&#34;和#34; somethingelse.requiresAdmin&#34;?这是&#34;出口&#34;与 myapp / packages / access / server / config / passport.js exports
:module.exports = function(passport) { ...}
,github相关?如果是这样,我们在什么情况下可以使用这个&#34;出口&#34;?
由于身份验证的授权规则是在包中写入的,因此访问&#34;并且在包&#34; mymodule&#34;中使用,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会自动链接所有软件包还是代码链接软件包?它是否由于部分与#34相关联;这是为了向后兼容&#34 ;如下所示?如果是这样,哪里可以&#34; auth&#34;使用?所有包 myapp / packages / ?在mean.io base app目录 myapp / 中怎么样?
var auth = require('./server/config/authorization');
// This is for backwards compatibility
mean.register('auth', function() {
return auth;
});
问题C:为什么&#34; Access.passport = passport;&#34;,但&#34;中间件&#34; for&#34; Access.middleware = auth;&#34;?如果是&#34; Access.auth = auth&#34;会发生什么?
答案 0 :(得分:0)
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's module documentation或this write-up on require
and exports
。
这个问题的答案是对问题A答案的补充。
有代码&#34;链接&#34;包裹。这是require
声明。
在您的app.js
源代码中,第一行(读取var mean = require('meanio')
)会将局部变量mean
设置为exports
对象所指定的值meanio.js
1}}和/或meanio
模块已加载。
与passport = require('passport')
相同。在这种情况下,加载index.js in the passport module后,局部变量passport
将等于exports
的值。
我不完全确定你在这里问的是什么,但是让我去试一试。
在这种情况下:
1){1}在第1行&#34;进口&#34; meanio模块,使局部变量var mean = require('meanio')
或多或少设置为等于meanio模块中mean
的值。
2)第2行中的exports
设置局部变量Module = mean.Module
等于Module
的值,该值必须在meanio模块中分配。
3)mean.Module
实例化var Access = new Module('access')
类的实例,将其分配给局部变量Module
。
4)Access
在名为Access.passport = passport
的{{1}}实例中分配名为passport
的实例变量(meanio.Module
模块{{1}的值在第3行#)
5)Access
在名为passport
的{{1}}实例中分配名为require
的实例变量(在第11行中由Access.middleware = auth
返回的值)
我不熟悉&#34; meanio&#34;模块,但基于此代码,您似乎正在配置middleward
实例(名为meanio.Module
),方法是指定特定的&#34; magic&#34;变量名。
换句话说,您可能拥有Access
或(而不是第5行)require('./server/config/authorization')
而不是meanio.Module("access")
。
那就是&#34; meanio&#34;的作者模块似乎决定使用特殊的变量名来配置类而不是&#34; setter&#34;传递给构造函数的方法或参数。我假设在meanio代码中的某个位置,您会找到Access
和Access.passport = passport; Access.middleware = auth
之类的引用,其中代码假定您已填充&#34;填充&#34;这些实例变量发生在代码示例的最后几行中。
如果您要添加Access.setPassport(passport); Access.setMiddleware(auth)
,那么所有会发生的事情是var Access = new Module('access',passport,auth)
对象会有一个名为this.middleware
的新属性,其值等于局部变量this.passport
的那个。
如果您使用Access.auth = auth
代替 Access
,我会假设auth
类中使用auth
的任何代码1}}将失败,因为没有为Access.auth
分配任何值,Access.middleware
不是#34;魔法&#34; meanio正在寻找的变量名。