SocketCluster Middleware HandShake with promise [英] SocketCluster Middleware HandShake with promise
问题描述
我正在构建一个同时提供 http 和 ws 服务的应用程序.用户首先通过 HTTP 登录到 Laravel 服务器.这将返回一个 JWT,用于允许通过 WS 登录.
Im building an app that serve both http and ws. Users login first over HTTP to a Laravel Server. That returns a JWT that is used to allow login over WS.
Ihv 添加了一个 MIDDLEWARE_HANDSHAKE 来获取令牌并向 Laravel 服务器发出请求以询问该令牌是否有效以及用户是否有权访问 WS(并非每个登录的用户都被允许访问 WS);
Ihv added a MIDDLEWARE_HANDSHAKE that gets the token and make a request to Laravel Server to ask if that token is valid and the user has access to WS (Not every logged user is allowed to WS);
客户端代码:
var options = {
host: '127.0.0.1:3000',
query: {
source: 'web',
token: '',
}
};
var socket;
$.post('http://127.0.0.1:8000/authenticate', {
email: 'chadd01@example.org',
password: '1234'
}, function(data, textStatus, xhr) {
options.query.token = data.token;
//ALL PERFECT UNTILL HERE
// Initiate the connection to the ws server
socket = socketCluster.connect(options)
.on('connect', function(data) {
console.log('CONNECTED', data);
})
.on('error', function(data) {
console.log('ERROR', data.message);
});
});
SocketCluster 服务器代码:
SocketCluster Server code:
scServer.addMiddleware(scServer.MIDDLEWARE_HANDSHAKE, function(request, next) {
var query = url.parse(request.url, true).query;
switch (query.source) {
case 'web':
case 'mobile-app':
validateUser(query)
.then((response) => {
next(); //Allowed
})
.catch((code) => {
next(code); //Blocked with StatusCode
});
break;
default:
next(true, 'NOT_AUTHORIZED'); // Block
break;
}
});
validateUser = (credentials = {}) => {
return new Promise((resolve, reject) => {
request({ url: API + 'webSocket/users/' + credentials.token, method: 'GET' }, (error, response, body) => {
if (response.statusCode === 200) {
resolve(body);
}
reject(response.statusCode);
});
});
};
在像这样实现这个中间件时,即使验证成功,我也会不断从 ws 服务器收到此响应:
While implementing this middleware like this i keep getting this response from ws server even when validation is successfull:
WebSocket connection to 'ws://127.0.0.1:3000/socketcluster/?source=web&token=<_TOKEN_>' failed: Connection closed before receiving a handshake response
(index):149 ERROR Socket hung up
但是,如果我像这样实现 HANDSHAKE_MIDDLEWARE:
But, if i implement the HANDSHAKE_MIDDLEWARE like this:
scServer.addMiddleware(scServer.MIDDLEWARE_HANDSHAKE, function(request, next) {
var validUser = true;
if (validUser){
return next();
}
return next('NOT_A_VALID_USER');
});
一切顺利:
CONNECTED Object {id: "W067vqBc9Ii8MuIqAAAC", pingTimeout: 20000, isAuthenticated: true, authToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbiI6I…xOTV9.E4bLPh4Vjk9ULvfhW6prjBbVt0vOD32k63L1vlDtGrU"}
所以问题似乎出在 Promise 回调上.
So the problem seems to be in the Promise callback.
如果这不是正确的实施方式,您有什么建议吗?
Any advice if this is not the right way to implement?
谢谢.
推荐答案
在 SocketCluster 上使用 JWT 的一个重要原因是处理登录和身份验证,您是否考虑过只使用 WS?
A big reason why JWT is used on SocketCluster is to handle logging in and authentication, have you considered just using WS?
您当前的 HTTP 代码如何检查登录数据,您可以对 WS 执行相同操作并使用 socket.setAuthToken
设置令牌 (这是我在我的项目):
Just how your current HTTP code check the login data, you can do the same for WS and use socket.setAuthToken
to set the token (here is an example that I used in my project):
socket.setAuthToken({
email: credentials.email,
id: returnedData.id,
permission: returnedData.permission
});
然后您可以向仍在使用 on/emit 的 WS 服务器发出请求,并检查它们是否已通过身份验证.这是我的 authCheck
函数的修改片段:
You can then do requests to the WS server still using on/emit, and do a check to see if they are authenticated. Here's a modified snippet of my authCheck
function:
const token = socket.getAuthToken();
if (token && token.email) {
console.log('Token Valid, User is: ', token.email);
// user validated - continue with your code
} else {
console.log('Token Invalid, User not authenticated.');
// respond with error message to the user
}
这篇关于SocketCluster Middleware HandShake with promise的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!