JWT를 사용하여 소켓 io 연결 인증


111

socket.io 연결을 어떻게 인증 할 수 있습니까? 내 응용 프로그램은 다른 서버 (python)의 로그인 엔드 포인트를 사용하여 토큰을 얻습니다. 사용자가 노드 측에서 소켓 연결을 열 때마다 해당 토큰을 어떻게 사용할 수 있습니까?

io.on('connection', function(socket) {
    socket.on('message', function(message) {
        io.emit('message', message);
    });
});

그리고 클라이언트 측 :

var token = sessionStorage.token;
var socket = io.connect('http://localhost:3000', {
    query: 'token=' + token
});

토큰이 파이썬으로 생성 된 경우 :

token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')

이 토큰을 사용하여 노드에서 소켓 연결을 인증하려면 어떻게해야합니까?

답변:


238

토큰이 다른 서버에서 생성되었는지 여부는 중요하지 않습니다. 올바른 비밀 키와 알고리즘이 있으면 계속 확인할 수 있습니다.

jsonwebtoken모듈로 구현

고객

const {token} = sessionStorage;
const socket = io.connect('http://localhost:3000', {
  query: {token}
});

섬기는 사람

const io = require('socket.io')();
const jwt = require('jsonwebtoken');

io.use(function(socket, next){
  if (socket.handshake.query && socket.handshake.query.token){
    jwt.verify(socket.handshake.query.token, 'SECRET_KEY', function(err, decoded) {
      if (err) return next(new Error('Authentication error'));
      socket.decoded = decoded;
      next();
    });
  }
  else {
    next(new Error('Authentication error'));
  }    
})
.on('connection', function(socket) {
    // Connection now authenticated to receive further events

    socket.on('message', function(message) {
        io.emit('message', message);
    });
});

socketio-jwt모듈로 구현

이 모듈은 클라이언트 측과 서버 측 모두에서 인증을 훨씬 쉽게 만듭니다. 그들의 예를 확인하십시오.

고객

const {token} = sessionStorage;
const socket = io.connect('http://localhost:3000');
socket.on('connect', function (socket) {
  socket
    .on('authenticated', function () {
      //do other things
    })
    .emit('authenticate', {token}); //send the jwt
});

섬기는 사람

const io = require('socket.io')();
const socketioJwt = require('socketio-jwt');

io.sockets
  .on('connection', socketioJwt.authorize({
    secret: 'SECRET_KEY',
    timeout: 15000 // 15 seconds to send the authentication message
  })).on('authenticated', function(socket) {
    //this socket is authenticated, we are good to handle more events from it.
    console.log(`Hello! ${socket.decoded_token.name}`);
  });

소켓에 들어오는 연결이 없더라도 소켓 서버를 시작하면 여전히 이전 토큰이 있습니다. 그게 이상해?
무르

클라이언트 API에 io.connect과 함께 사용할 수있는 옵션은 무엇입니까
rocketspacer

2
사용자가 원래 권한이없고 첫 번째 시도에서 비밀이없는 경우 어떻게 서버에 다시 연결합니까?
sznrbrt

10
안녕하세요, 물어볼 필요가 있습니다. 토큰은 연결시 또는 모든 방출 이벤트에서 한 번 필요합니까?
Krunal Limbad

3
받는 사람을 위해 Cannot read property 'on' of undefined; 단지를 제거 socket에서 function(socket).
Thomas Orlita 19.04.24
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.