使用JWT令牌。 有更好的方法吗?

我通过nJWT包使用JWT令牌,使用socket.io-jwt包将我的用户validation到我的Socket.io。

或多或less,代码看起来像这样。 用户通过HTML表单发送POST请求来播放/login以生成JWT令牌。 然后,socket.io客户端使用该令牌进行初始化。

/** * Create Express server. */ const app = express(); const http = require('http').Server(app); const io = require('socket.io')(http); const socketioJwt = require('socketio-jwt'); app.set('jwt.secret', secureRandom(256, { type: 'Buffer' })); app.post('/play/login', (req, res) => { // validate user's req.body.email and req.body.password const claims = { iss: "http://app.dev", // The URL of your service sub: "user-1", // The UID of the user in your system scope: "game" }; const jwt = nJwt.create(claims, app.get("jwt.secret")); const token = jwt.compact(); new Cookies(req,res).set('access_token', token, { httpOnly: true, secure: process.env.ENVIRONMENT === "production" }); tokenUserRelations[token] = req.body.email; res.json({ code: 200, token: token }); }); /** * Add Socket IO auth middleware */ io.set('authorization', socketioJwt.authorize({ secret: app.get("jwt.secret"), handshake: true })); io.sockets.on('connection', function (socket) { socket.on('chat message', function (req) { io.emit("chat message emit", { email: tokenUserRelations[socket.handshake.query.token], msg: req.msg }); }); socket.on('debug', function (req) { io.emit("debug emit", { playersOnline: Object.keys(tokenUserRelations).length }); }); socket.on('disconnect', function (req) { delete tokenUserRelations[socket.handshake.query.token]; }); }); io.listen(app.get('socket.port'), () => { console.log('Started! Socket server listening on port %d in %s mode', app.get('socket.port'), app.get('env')); }); 

现在,它正常工作,但为了跟踪令牌邮件,我必须这样做:

 tokenUserRelations[token] = req.body.email; 

所以我可以把令牌指向哪个用户。

我有一种感觉,将令牌电子邮件关系保存在一个全局对象中,将来会让我头痛,特别是当令牌/ cookies过期的时候。

有没有更好的办法呢? 我需要知道哪个用户的JWT令牌指向,所以我可以做一些业务逻辑与他们。

谢谢。

令牌可以包含任何你想要的信息,这个信息是沿着令牌encryption的。

你可以做的是在令牌中encryption一个用户ID,当你收到一个请求时,解密这个令牌(当你validation它的时候是这样做的),并且正常地使用这个用户ID。

这样,如果令牌过期,新的令牌将具有相同的用户ID,并且您的代码不会受到影响。

这是我在我的一个networking应用程序中做的,而且工作正常。 不过,我正在使用官方的jwt模块

你不会在代码中显示如何创build或维护tokenUserRelations,但只要我听到“全局”,我的脑海中就会出现红旗。

JWT标准包括将“索赔”embedded到令牌本身中的概念; 你已经这样做了你的claims不变。 该数据格式是任意的,只要整个JWT得到validation,就可以被您的应用程序信任。 请注意,您需要validation每个请求的JWT。 所以,将电子邮件填入索赔对象不是很好,这是大多数人所做的。

作为旁注,你应该小心你现在如何设置你的'jwt.secret'。 每当应用程序启动时,现在都会生成一个新的应用程序,这意味着a)您的所有用户都将被注销,并且每次重新启动应用程序时都必须重新login,并且b)您无法使用多个进程或多个服务器,如果你将来需要的话。

更好的办法是从环境中(例如,一个envvariables),而不是在应用程序启动时生成它,除非你只是为了debugging目的而这样做。

添加上面的优秀答案,如果您决定将jwt.secret存储在一个文件中,并在代码加载的时候将其添加到您的git存储库(或者您正在使用的任何其他VCS) )。 确保在.gitignore文件中包含“jwt.secret”的path。 然后,当准备好部署生产代码时,可以按照build议将该密钥设置为环境variables。 如果您需要重置密钥,您将在本地环境中logging该密钥。

使用JWT是保护您的api的绝佳方便方法,但遵循最佳实践至关重要。