SocketCluster Middleware HandShake with promise [英] SocketCluster Middleware HandShake with promise

查看:57
本文介绍了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?

看看 SocketCluster 身份验证.

您当前的 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆