SocketCluster中间件握手与承诺
我build立一个既服务于http和ws的应用程序。 用户首先通过HTTPlogin到Laravel服务器。 这将返回一个用于允许通过WSlogin的JWT。
Ihv添加了一个MIDDLEWARE_HANDSHAKE,它获取该令牌并向Laravel Server发出请求,询问该令牌是否有效,并且该用户有权访问WS(并非每个已login的用户都可以访问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服务器代码:
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); }); }); };
当像这样实现这个中间件时,即使validation成功,我也不断从ws服务器获取这个响应:
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:
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"}
所以问题似乎在Promisecallback中。
任何意见,如果这不是正确的方式来实施?
谢谢。
为什么在SocketCluster上使用JWT的一个重要原因是处理login和authentication,你有没有考虑过使用WS?
看看SocketCluster身份validation 。
只要您当前的HTTP代码如何检查login数据,您可以对WS执行相同的操作,并使用socket.setAuthToken
来设置令牌(以下是我在项目中使用的示例) :
socket.setAuthToken({ email: credentials.email, id: returnedData.id, permission: returnedData.permission });
然后,您可以对仍在使用on / emit的WS服务器执行请求,并检查它们是否已通过身份validation。 以下是我的authCheck
函数的修改片段:
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 }
- yarn install error在Docker构build过程中找不到package.json
- XMLHttpRequest未在platform-browser-dynamic.umd.js中定义