我在服务器端使用Node.js和Passportjs的组合,在客户端使用Emberjs作为应用程序。我当前的身份验证策略是使用Passport来以普通电子邮件/密码组合作为标准对用户进行身份验证,然后挂接会话创建机制以生成身份验证令牌,该令牌被保存到一个单独的表中,然后传回给用户,以便在任何进一步的受保护路由中使用。(传入REST标题)。
创建令牌是很好的,我是这样做的,没有问题,但是如果我需要额外的一步的话,我很难解决这个问题。
目前,我使用节点-jwt-简单生成令牌,使用随机节点-uuid pass作为有效负载,用户UID (另一个节点-uuid)作为秘密。然后,我将其保存到客户端的$.cookie
、服务器端的表以及创建日期。
显然,节点-jwt-简单中的一个步骤是对令牌进行编码。还提供了解码功能。我的问题是,在我进行auth检查时,是否需要将令牌解码成某种东西,还是只需要检查用户的会话cookie (REST头),以便与数据库中的令牌匹配?我不想费尽心机地生成一个令牌,结果却错过了一个重要的步骤,但我不知道如何将它解码成任何能够提供任何额外的有用安全性的东西。
更新:
我想我昨晚解决了这个问题
解决方案似乎是使用用户的UID作为JWT的有效负载,将静态字符串作为秘密(取自类似于服务器环境变量或类似的内容),然后只将编码的令牌存储在数据库中。将令牌传回给客户端,以便重新使用,然后当客户端试图访问受保护的路由时,他们必须将它们的UID连同编码的令牌一起传递给服务器,然后服务器被解码,并将解码的有效负载与已传递的UID相比较。如果它们匹配,那么auth就成功了,否则令牌就会被销毁,用户必须再次登录。通过这样做,它使令牌的存储实际上是毫无用处的,而不知道秘密密钥,也不知道用户的UID,但却使auth进程更加安全。
发布于 2013-12-08 17:12:58
如果您不验证令牌,您还可以创建一些其他随机数据作为会话cookie使用,只要它是唯一的,并且不能被客户端猜测。
但是,由于您已经做了大量的工作,您可以在令牌中编码一些有用的东西,它可以告诉您它的有效时间,例如exp
字段,因此您不必从数据库中读取。
我不确定我是否完全理解您的JWT,但我看到的问题是,您需要信息来解码可能不在您手上的令牌。所以你必须在你的数据库里搜索。
我认为使用一些随机会话密钥就足够了,例如,以下功能:
var crypto = require('crypto');
/**
* Create random bytes and encode base64url.
* @param {int} [lengthInBytes=40] the size of the raw token in bytes
* (will be longer since base64url-encoded)
* @param {function} callback node-style callback-function;
* data-parameter is a string w/ a shortened (no trailing ==)
* base64url-encoded string of the generated bytes.
*/
exports.createRandomToken = function createRandomToken(lengthInBytes, callback) {
if (typeof lengthInBytes === 'function') {
callback = lengthInBytes;
lengthInBytes = 40;
}
crypto.randomBytes(lengthInBytes, function (ex, buf) {
if (ex) {
callback(ex);
return;
}
callback(null, buf.toString('base64')
.replace(/\//g, '_')
.replace(/\+/g, '-')
.replace(/=/g, ''));
});
};
发布于 2016-07-19 08:37:03
https://stackoverflow.com/questions/20455161
复制相似问题