在某些操作或断开连接时识别用户
identifying users upon some action or disconnected
我是节点新手
我有一个 PHP/Laravel cms,我有一个简单的 Nodejs 游戏服务器,它基本上是一个生成一些数字的循环
我通过 Socketio 将我的 PHP 后端连接到 Nodejs 并使用 Socketio-JWT
来识别用户
我的客户端 (php/laravel)
PHP
$userToken = JWTAuth::customClaims(['userid' => Auth::user()->id, 'name' => Auth::user()->name, 'avatar' => asset_url('image/avatar-default.png')])->fromUser(Auth::user() );
html/js
var socket = io.connect("http://localhost:666");
socket.on('connect', function () {
socket.emit('authenticate', {token: '{{$userToken}}'});
});
socket.on('authenticated', function () {
console.log('Authenticated');
});
socket.on('unauthorized', function (data) {
console.log('Unauthorized, error msg: ' + data.message);
});
我的服务器端
const _online_users = { };
io.sockets
.on('connection', socketioJwt.authorize({
secret: JWT_SECRET,
timeout: 15000
}))
.on('authenticated', function(socket) {
_online_users[socket.decoded_token.userid] = {
name : socket.decoded_token.name ,
avatar : socket.decoded_token.avatar ,
}
io.sockets.emit('update_online_users' , _online_users );
socket.on('disconnect', function() {
console.log(`----- @@disconnect -----`)
});
}) ;
如您所见,我有一个名为 _online_users
的对象,我将经过身份验证的用户存储在该对象中,然后将其发送给客户端,以便他们知道谁在线
io.sockets.emit('update_online_users' , _online_users );
这是问题所在,当用户断开连接时
socket.on('disconnect', function() {
console.log(`----- @@disconnect -----`)
});
我必须更新我的 _online_users
对象并删除断开连接的用户....我应该怎么做?我在想也许我可以将令牌本身存储在 _online_users
_online_users[socket.decoded_token.userid] = {
token : socket.token ,
name : socket.decoded_token.name ,
avatar : socket.decoded_token.avatar ,
}
当用户断开连接时,我从套接字中获取断开连接的令牌,并通过该令牌从对象中删除用户
当然,这都是理论!我不确定这是否是要走的路......首先,我无法从套接字访问令牌本身!
或者假设其中一个用户向节点服务器发送了另一个请求,我如何识别发送请求的用户?
.on('authenticated', function(socket) {
socket.on('somaction', function() {
console.log(` who is this guy ? `)
});
})
socket.decoded_token
中有什么独特之处可以用作 ID 吗?如果是这样,我可以将它存储在在线用户中,当用户请求某些东西时来回发送它
基本上我迷路了,感谢任何指点
您现在可以在 socket-io
的较新版本中使用中间件。因此,您可以检查用户是否通过随请求发送的 jwt
令牌登录。如果解码成功,您可以将用户信息分配给当前套接字并调用 next()
并转到您正在监听的事件。这是 socket-io 文档中提供的示例,针对您的情况稍作修改。
io.use(function(socket, next) {
const handshakeData = socket.request;
// make sure the handshake data looks good as before
// if error do this:
// next(new Error('not authorized'));
// else decode jwt token here and append the user to the socket.request
// and call next
// pseudo code here
const {
authorization
} = handshakeData.header
let token;
if (authorization && authorization.split(" ")[0] === "Bearer") {
token = authorization.split(" ")[1]
}
let user = jwt.decode(token, secret);
socket.request.user = user;
next();
});
你做得很好!
由于您在 'authenticated'
处理程序中添加了 socket
事件处理程序,您仍然可以访问 socket.decoded_token.userid
.
这应该足够了:
const _online_users = {};
io.sockets
.on('connection', socketioJwt.authorize({
secret: JWT_SECRET,
timeout: 15000
}))
.on('authenticated', function(socket) {
_online_users[socket.decoded_token.userid] = {
name: socket.decoded_token.name,
avatar: socket.decoded_token.avatar,
};
io.sockets.emit('update_online_users', _online_users);
socket.on('disconnect', function() {
console.log(`----- @@disconnect -----`);
delete _online_users[socket.decoded_token.userid];
io.sockets.emit('update_online_users', _online_users);
});
});
或者更简洁一点:
const _online_users = {};
io.sockets
.on('connection', socketioJwt.authorize({
secret: JWT_SECRET,
timeout: 15000
}))
.on('authenticated', function(socket) {
const { avatar, name, userid } = socket.decoded_token;
_online_users[userid] = { name, avatar };
io.sockets.emit('update_online_users', _online_users);
socket.on('disconnect', function() {
delete _online_users[userid];
io.sockets.emit('update_online_users', _online_users);
});
socket.on('any other event...', function() {
// ... still have access to userid
});
});
编辑:关于未验证的套接字我不知道;医生什么也没说。你可以尝试这样的事情:
io.socket.on('connection', socket => {
socket.emit('update_online_users', _online_users);
// I'm afraid this closes the socket if unauthorized, you could check by yourself
socketioJwt.authorize({
secret: JWT_SECRET,
timeout: 15000
})(socket);
}).on('authenticated', socket => {
//...
});
希望对您有所帮助。
我是节点新手
我有一个 PHP/Laravel cms,我有一个简单的 Nodejs 游戏服务器,它基本上是一个生成一些数字的循环
我通过 Socketio 将我的 PHP 后端连接到 Nodejs 并使用 Socketio-JWT
来识别用户
我的客户端 (php/laravel)
PHP
$userToken = JWTAuth::customClaims(['userid' => Auth::user()->id, 'name' => Auth::user()->name, 'avatar' => asset_url('image/avatar-default.png')])->fromUser(Auth::user() );
html/js
var socket = io.connect("http://localhost:666");
socket.on('connect', function () {
socket.emit('authenticate', {token: '{{$userToken}}'});
});
socket.on('authenticated', function () {
console.log('Authenticated');
});
socket.on('unauthorized', function (data) {
console.log('Unauthorized, error msg: ' + data.message);
});
我的服务器端
const _online_users = { };
io.sockets
.on('connection', socketioJwt.authorize({
secret: JWT_SECRET,
timeout: 15000
}))
.on('authenticated', function(socket) {
_online_users[socket.decoded_token.userid] = {
name : socket.decoded_token.name ,
avatar : socket.decoded_token.avatar ,
}
io.sockets.emit('update_online_users' , _online_users );
socket.on('disconnect', function() {
console.log(`----- @@disconnect -----`)
});
}) ;
如您所见,我有一个名为 _online_users
的对象,我将经过身份验证的用户存储在该对象中,然后将其发送给客户端,以便他们知道谁在线
io.sockets.emit('update_online_users' , _online_users );
这是问题所在,当用户断开连接时
socket.on('disconnect', function() {
console.log(`----- @@disconnect -----`)
});
我必须更新我的 _online_users
对象并删除断开连接的用户....我应该怎么做?我在想也许我可以将令牌本身存储在 _online_users
_online_users[socket.decoded_token.userid] = {
token : socket.token ,
name : socket.decoded_token.name ,
avatar : socket.decoded_token.avatar ,
}
当用户断开连接时,我从套接字中获取断开连接的令牌,并通过该令牌从对象中删除用户
当然,这都是理论!我不确定这是否是要走的路......首先,我无法从套接字访问令牌本身!
或者假设其中一个用户向节点服务器发送了另一个请求,我如何识别发送请求的用户?
.on('authenticated', function(socket) {
socket.on('somaction', function() {
console.log(` who is this guy ? `)
});
})
socket.decoded_token
中有什么独特之处可以用作 ID 吗?如果是这样,我可以将它存储在在线用户中,当用户请求某些东西时来回发送它
基本上我迷路了,感谢任何指点
您现在可以在 socket-io
的较新版本中使用中间件。因此,您可以检查用户是否通过随请求发送的 jwt
令牌登录。如果解码成功,您可以将用户信息分配给当前套接字并调用 next()
并转到您正在监听的事件。这是 socket-io 文档中提供的示例,针对您的情况稍作修改。
io.use(function(socket, next) {
const handshakeData = socket.request;
// make sure the handshake data looks good as before
// if error do this:
// next(new Error('not authorized'));
// else decode jwt token here and append the user to the socket.request
// and call next
// pseudo code here
const {
authorization
} = handshakeData.header
let token;
if (authorization && authorization.split(" ")[0] === "Bearer") {
token = authorization.split(" ")[1]
}
let user = jwt.decode(token, secret);
socket.request.user = user;
next();
});
你做得很好!
由于您在 'authenticated'
处理程序中添加了 socket
事件处理程序,您仍然可以访问 socket.decoded_token.userid
.
这应该足够了:
const _online_users = {};
io.sockets
.on('connection', socketioJwt.authorize({
secret: JWT_SECRET,
timeout: 15000
}))
.on('authenticated', function(socket) {
_online_users[socket.decoded_token.userid] = {
name: socket.decoded_token.name,
avatar: socket.decoded_token.avatar,
};
io.sockets.emit('update_online_users', _online_users);
socket.on('disconnect', function() {
console.log(`----- @@disconnect -----`);
delete _online_users[socket.decoded_token.userid];
io.sockets.emit('update_online_users', _online_users);
});
});
或者更简洁一点:
const _online_users = {};
io.sockets
.on('connection', socketioJwt.authorize({
secret: JWT_SECRET,
timeout: 15000
}))
.on('authenticated', function(socket) {
const { avatar, name, userid } = socket.decoded_token;
_online_users[userid] = { name, avatar };
io.sockets.emit('update_online_users', _online_users);
socket.on('disconnect', function() {
delete _online_users[userid];
io.sockets.emit('update_online_users', _online_users);
});
socket.on('any other event...', function() {
// ... still have access to userid
});
});
编辑:关于未验证的套接字我不知道;医生什么也没说。你可以尝试这样的事情:
io.socket.on('connection', socket => {
socket.emit('update_online_users', _online_users);
// I'm afraid this closes the socket if unauthorized, you could check by yourself
socketioJwt.authorize({
secret: JWT_SECRET,
timeout: 15000
})(socket);
}).on('authenticated', socket => {
//...
});
希望对您有所帮助。