向 Mean.io 初学者解释 Mean.io 示例包的身份验证如何工作
Posted
技术标签:
【中文标题】向 Mean.io 初学者解释 Mean.io 示例包的身份验证如何工作【英文标题】:Explain to Mean.io beginner how Mean.io sample package's authentication works 【发布时间】:2014-10-10 23:49:30 【问题描述】:我从this tutorial video 学习mean.io,它显示了示例包(由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”?这是“exports”吗? " 与 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 是否会自动链接所有包,或者是否有代码将包链接到某个地方? 是否由于下面显示的“这是为了向后兼容”部分而链接的?如果是这样,“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;”是“middleware”?如果是“Access.auth =授权”?
【问题讨论】:
就exports
而言,这是 Node 模块系统的一部分。每当您require
某事时,您都会从所需文件中获得exports
对象。
关于问题 A,请参阅***.com/questions/5311334/…
【参考方案1】:
关于问题 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
将在加载index.js in the passport module 后等于exports
的值。
关于问题 C
我不完全确定你在这里问什么,但让我试一试。
在这种情况下:
1) 第 1 行中的var mean = require('meanio')
“导入”meanio 模块,使得局部变量mean
或多或少地设置为等于meanio 模块中exports
的值。
2) 第 2 行中的 Module = mean.Module
将局部变量 Module
设置为等于 mean.Module
的值,该值必须在 meanio 模块中分配。
3) var Access = new Module('access')
正在实例化Module
类的一个实例,并将其分配给局部变量Access
。
4) Access.passport = passport
在名为 Access
的 meanio.Module
实例中分配名为 passport
的实例变量(赋值给第 3 行的 passport
模块 require
d 的值)
5) Access.middleware = auth
在名为 Access
的 meanio.Module
的实例中分配名为 middleward
的实例变量(赋值给第 11 行中 require('./server/config/authorization')
返回的值)。
我不熟悉“meanio”模块,但根据此代码,您似乎正在通过分配特定的“魔术”变量名称来配置 meanio.Module("access")
实例(名为 Access
)。
换句话说,您可能有Access.setPassport(passport); Access.setMiddleware(auth)
或(而不是第5 行)var Access = new Module('access',passport,auth)
,而不是Access.passport = passport; Access.middleware = auth
。
也就是说,“meanio”模块的作者似乎决定使用特殊的变量名来配置类,而不是“setter”方法或传递给构造函数的参数。我假设在 meanio 代码的某处,您会找到对 this.middleware
和 this.passport
之类的引用,其中代码假设您已经“填充”了这些实例变量,就像代码示例的最后几行中发生的那样.
如果您要添加Access.auth = auth
,那么将会发生的只是Access
对象将具有一个名为auth
的新属性,其值 等于局部变量的值auth
.
如果你使用Access.auth
而不是 of Access.middleware
,我假设Access
类中使用this.middleware
的任何代码都会失败,因为没有值曾经被分配给Access.middleware
,而Access.auth
不是meanio 正在寻找的“神奇”变量名之一。
【讨论】:
以上是关于向 Mean.io 初学者解释 Mean.io 示例包的身份验证如何工作的主要内容,如果未能解决你的问题,请参考以下文章
未捕获的 ReferenceError:未定义角度 - Mean.IO