首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >承诺的SocketCluster中间件HandShake

承诺的SocketCluster中间件HandShake
EN

Stack Overflow用户
提问于 2017-02-22 14:54:33
回答 1查看 748关注 0票数 3

我正在构建一个同时为http和ws服务的应用程序。用户首先通过HTTP登录到Laravel。返回用于允许在WS上登录的JWT。

Ihv添加了一个MIDDLEWARE_HANDSHAKE,它获取令牌并向Laravel发出请求,询问该令牌是否有效,用户是否有权访问WS (并非每个登录的用户都允许WS);

客户代码:

代码语言:javascript
复制
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服务器代码:

代码语言:javascript
复制
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服务器获得响应,即使验证成功了:

代码语言:javascript
复制
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:

代码语言:javascript
复制
scServer.addMiddleware(scServer.MIDDLEWARE_HANDSHAKE, function(request, next) {
    var validUser = true;
    if (validUser){
         return next();
    }
    return next('NOT_A_VALID_USER');
});

一切都很好:

代码语言:javascript
复制
CONNECTED Object {id: "W067vqBc9Ii8MuIqAAAC", pingTimeout: 20000, isAuthenticated: true, authToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbiI6I…xOTV9.E4bLPh4Vjk9ULvfhW6prjBbVt0vOD32k63L1vlDtGrU"}

因此,问题似乎在于承诺的回调。

如果这不是正确的实施方式,有什么建议吗?

谢谢。

EN

回答 1

Stack Overflow用户

发布于 2017-07-27 10:12:37

在SocketCluster上使用JWT的一个重要原因是处理登录和身份验证,您考虑过只使用WS吗?

看看SocketCluster认证

正如当前HTTP代码如何检查登录数据一样,您也可以对WS执行同样的操作,并使用socket.setAuthToken设置令牌(下面是我在项目中使用的一个示例)。

代码语言:javascript
复制
socket.setAuthToken({
    email: credentials.email,
    id: returnedData.id,
    permission: returnedData.permission
});

然后,您可以对仍在使用/emit的WS服务器进行请求,并检查它们是否经过身份验证。下面是我的authCheck函数的修改片段:

代码语言:javascript
复制
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
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42394884

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档