2017-02-22 42 views
2

Im создание приложения, которое обслуживает как http, так и ws. Пользователи сначала загружаются через HTTP на сервер Laravel. Это возвращает JWT, который используется для разрешения входа через WS.SocketCluster Middleware HandShake с обещанием

Ihv добавил MIDDLEWARE_HANDSHAKE, который получает маркер и запрашивает сервер Laravel, чтобы узнать, является ли этот токен допустимым, и пользователь имеет доступ к WS (не каждому зарегистрированному пользователю разрешено WS);

код

Клиент:

var options = { 
    host: '127.0.0.1:3000', 
    query: { 
     source: 'web', 
     token: '', 
    } 
}; 

var socket; 

$.post('http://127.0.0.1:8000/authenticate', { 
    email: '[email protected]', 
    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); 
     }); 
    }); 

}; 

При реализации этого промежуточного уровня, как это я получаю этот ответ от 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"} 

Таким образом, проблема, кажется, в обратном вызове Promise.

Любой совет, если это неправильный способ реализации?

Спасибо.

ответ

0

Большая причина, по которой JWT используется на SocketCluster, заключается в том, чтобы обрабатывать вход в систему и аутентификацию, считали ли вы, что используете только WS?

Посмотрите на SocketCluster authentication.


Просто, как ваш текущий код HTTP проверяет данные входа в систему, вы можете сделать то же самое для WS и использовать socket.setAuthToken для установки маркера (здесь пример, который я использовал в моем проекте):

socket.setAuthToken({ 
    email: credentials.email, 
    id: returnedData.id, 
    permission: returnedData.permission 
}); 

Затем вы можете выполнять запросы на сервер WS, все еще использующий on/emit, и выполнить проверку, чтобы проверить, не аутентифицированы ли они. Ниже приведен модифицированный фрагмент моей функции 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 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^