Xác thực kết nối socket io bằng JWT


106

Làm cách nào để xác thực kết nối socket.io? Ứng dụng của tôi sử dụng điểm cuối đăng nhập từ máy chủ khác (python) để lấy mã thông báo, làm cách nào để tôi có thể sử dụng mã thông báo đó bất cứ khi nào người dùng mở kết nối ổ cắm ở phía nút?

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

Và phía khách hàng:

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

Nếu mã thông báo được tạo bằng python:

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

Làm cách nào để sử dụng mã thông báo này để xác thực kết nối socket trong nút?

Câu trả lời:


226

Không quan trọng nếu mã thông báo được tạo trên máy chủ khác. Bạn vẫn có thể xác minh nó nếu bạn có khóa bí mật và thuật toán phù hợp.

Thực hiện với jsonwebtokenmô-đun

khách hàng

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

Người phục vụ

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);
    });
});

Thực hiện với socketio-jwtmô-đun

Mô-đun này làm cho việc xác thực dễ dàng hơn nhiều ở cả phía máy khách và máy chủ. Chỉ cần kiểm tra các ví dụ của họ.

khách hàng

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
});

Người phục vụ

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}`);
  });

Tôi đang gặp phải sự cố, mặc dù không có kết nối đến với ổ cắm, khi tôi kích hoạt máy chủ ổ cắm, nó vẫn có mã thông báo cũ. Đó có kì dị không ?
Lamour

Các tùy chọn có sẵn với io.connect trong api khách hàng là gì
rocketspacer

2
Bạn sẽ kết nối lại với máy chủ như thế nào trong trường hợp người dùng ban đầu không được phép và nó không có bí mật ở lần thử đầu tiên?
sznrbrt

9
xin chào, tôi cần hỏi, mã thông báo được yêu cầu một lần khi kết nối hoặc trong mỗi sự kiện phát hành?
Krunal Limbad

2
Đối với bất kỳ ai nhận được Cannot read property 'on' of undefined; chỉ cần loại bỏ sockettừ function(socket).
Thomas Orlita

-28

bạn có thể sử dụng url này.

var socket = SocketIOClient(socketURL: URL(string: "http://00.00.00.00:port")!, config: SocketIOClientConfiguration(arrayLiteral: SocketIOClientOption.connectParams(["token": "your secret key"])))

9
Bạn nên nói rõ rằng bạn đang viết một ngôn ngữ nhanh. Những người khác không biết điều đó.
Sword Jason,

6
Bạn cần giải thích câu trả lời này nếu không thì điều này không hữu ích cho tất cả mọi người. Ngoài ra nếu nó được viết bằng ngôn ngữ nhanh chóng xin vui lòng đề cập rằng trong câu trả lời của bạn
Freddy Daniel
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.