我在学习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/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.js 的
exports
有关:module.exports = function(passport) { ...}
, github ?如果是这样,我们在什么情况下可以使用这种“导出”?由于身份验证的授权规则写在“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
的代码。 s 源文件。
例如,给定文件 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
.关于问题 B(关于“链接”包)
这个问题的答案是对问题 A 答案的补充。
有代码可以“链接”这些包。它是
require
陈述。在您的
app.js
源代码,第一行(阅读 var mean = require('meanio')
)将设置局部变量 mean
分配给 exports
的任何值对象是 meanio.js
和/或 meanio
模块已加载。与
passport = require('passport')
相同.在这种情况下,局部变量 passport
将等于 exports
的值在 index.js in the passport module 之后已加载。关于问题 C
我不完全确定你在这里问什么,但让我试一试。
在这种情况下:
1)
var mean = require('meanio')
在第 1 行“导入”meanio 模块,使得局部变量 mean
或多或少等于 exports
的值在 meanio 模块中。2)
Module = mean.Module
在第 2 行设置局部变量 Module
等于 mean.Module
的值,必须在 meanio 模块中分配。3)
var Access = new Module('access')
正在实例化 Module
的实例类,将其分配给局部变量 Access
.4)
Access.passport = passport
分配名为 passport
的实例变量在 meanio.Module
的实例中命名为 Access
(到第 3 行的 passport
模块 require
d 的值)5)
Access.middleware = auth
分配名为 middleward
的实例变量在 meanio.Module
的实例中命名为 Access
(到第 11 行 require('./server/config/authorization')
返回的值)。我不熟悉“meanio”模块,但根据这段代码,您似乎正在配置
meanio.Module("access")
实例(名为 Access
)通过分配特定的“魔术”变量名称。换句话说,而不是
Access.passport = passport; Access.middleware = auth
你可能有 Access.setPassport(passport); Access.setMiddleware(auth)
或(而不是第 5 行)var Access = new Module('access',passport,auth)
.也就是说,“meanio”模块的作者似乎已经决定使用特殊的变量名来配置类,而不是“setter”方法或传递给构造函数的参数。我假设在 meanio 代码的某个地方,您会找到对
this.middleware
之类的引用。和 this.passport
,其中代码假设您已经“填充”了这些实例变量,就像代码示例的最后几行中发生的那样。如果您要添加
Access.auth = auth
那么将会发生的只是Access
对象将有一个名为 auth
的新属性其值等于局部变量 auth
的值.如果您使用
Access.auth
而不是 Access.middleware
, 我假设 Access
中的任何代码使用 this.middleware
的类将失败,因为从未为 Access.middleware
分配任何值和 Access.auth
不是 meanio 正在寻找的“神奇”变量名称之一。
关于node.js - 向 Mean.io 初学者解释 Mean.io 示例包的身份验证如何工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25356973/