【发布时间】:2014-11-13 10:10:30
【问题描述】:
我正在开发一个处理来自 Mongo 数据库的资源的网络应用程序,对于这些资源,我想提供一个 API,以便未来的移动应用程序可以从原始客户端获取或使用它。
但是,我希望 Web 应用使用相同的 API,在这里我对如何正确实现这一点感到有些困惑。
这是我到目前为止所做的:
API 认证:
app.route('/api/auth/')
.post(function (request,response) {
var email = request.body.email;
var password = request.body.password;
var login = new Account({"local.email":email,"local.password":password});
Account.findOne({"local.email":email}, function (err,user) {
if (err) {
response.send(500);
}
if (!user) {
response.send(404);
}
else {
user.validPassword(password, function (err,matched) {
if (err) {
response.send(500);
}
if (matched) {
var uuidToken = uuid.v4();
redisClient.set(uuidToken,user._id,redis.print);
redisClient.expire(user._id,100);
response.send(uuid);
}
else {
response.send(403);
}
});
}
});
});
所以基本上我会收到消费者的用户名和密码,然后根据数据库对其进行身份验证,如果匹配,我会回复一个令牌(实际上是一个UUID)。该令牌与数据库中的用户 ID 配对存储在 Redis 中。未来对任何 API 路由的每个请求都将验证此类令牌是否存在。
我想知道:
- 我应该如何管理令牌 TTL,以及在未来请求时续订?
- 如何控制每个时间窗口的请求限制?
- 我采取的方法是否有任何安全警告?
网站验证:
基本上我对数据库执行相同的用户名-密码身份验证,然后:
1.启动一个新的服务器会话。
2。当然,提供一个带有会话 ID 的 cookie。
3.然后我创建了 Redis UUID 和用户 ID 记录,API 将检查该记录。我想这没关系,因为请求POST /api/auth 再次进行身份验证是有任何意义的。
我想知道:
- 这是最好的方法吗?
- 我是否应该包含任何令牌盐来区分纯 API 消费请求和来自 Web 应用程序的请求?
- 我采取的方法是否有任何安全警告?
- 我应该包含更多令牌吗?
这是POST /login的例子:
app.route('/login')
.post(function (request,response,next) {
var email = request.body.email;
var password = request.body.password;
var login = new Account({"local.email":email,"local.password":password});
Account.findOne({"local.email":email}, function (err,user) {
if (err) {
response.redirect('/error');
}
if (!user) {
var cookie = request.cookies.userAttempts;
if (cookie === undefined) {
response.cookie('userAttempts',1);
}
else {
response.cookie('userAttempts',(++cookie));
}
response.redirect('/');
}
else {
user.validPassword(password, function (err,matched) {
if (err) {
// Redirect error site or show err message.
response.redirect('/error');
}
if (matched) {
var session = request.session;
session.userid = user._id;
var uuidToken = uuid.v4();
redisClient.set(uuidToken,user._id,redis.print);
redisClient.expire(uuidToken,900);
response.cookie('email',email);
response.redirect('/start');
}
else {
var cookie = request.cookies.passwordAttemps;
if (cookie === undefined)
response.cookie('passwordAttemps',1);
else {
var attemps = ++request.cookies.attemps
response.cookie('passwordAttemps', attemps)
}
response.redirect('/');
}
});
}
});
})
我认为我可以摆脱使用和编写典型的会话实现,并以某种方式依赖 API 所具有的类似的基于令牌的身份验证。
【问题讨论】:
标签: node.js api authentication