使用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的绝佳方便方法,但遵循最佳实践至关重要。
- NodeJS:在客户端存储JWT的地方? sessionStorage,localStorage还是cookies?
- 在iOS / Node应用程序中使用google / twitter / linkedInauthentication
- 护照facebook战略投掷数据必须是使用Node.js的string
- 用户使用socket.io进行身份validation
- 使用json文章的摘要authentication的curl命令
- 我无法使用passport-facebook来validation路线
- NodeJS Passport:通过两种策略multilogin – 序列化问题
- 有没有人用过Mongoose-auth? 你如何搭配findOrCreateUsers?
- Firebase child.once在auth.signInWithEmailAndPasswordcallback中超时不一致