Средние сервисы
Функция среднего сервиса — это функция, которая выполняется для каждого входящего подключения.
Функции среднего сервиса могут быть полезны для:
- ведения журнала
- аутентификации/авторизации
- лимитирования скорости
Примечание: эта функция будет выполнена только один раз на подключение (даже если подключение состоит из нескольких HTTP-запросов).
Регистрация среднего сервиса
Функция среднего сервиса имеет доступ к экземпляру Socket и к следующей зарегистрированной функции среднего сервиса.
io.use((socket, next) => {
if (isValid(socket.request)) {
next();
} else {
next(new Error("invalid"));
}
}); |
Вы можете зарегистрировать несколько функций среднего сервиса, и они будут выполнены последовательно:
io.use((socket, next) => {
next();
});
io.use((socket, next) => {
next(new Error("thou shall not pass"));
});
io.use((socket, next) => {
// not executed, since the previous middleware has returned an error
next();
}); |
Пожалуйста, убедитесь, что вы вызываете next() в любом случае. В противном случае подключение будет зависнуть, пока не будет закрыто после заданного таймаута.
Отправка учетных данных
Клиент может отправить учетные данные с помощью опции auth:
// plain object
const socket = io({
auth: {
token: "abc"
}
});
// or with a function
const socket = io({
auth: (cb) => {
cb({
token: "abc"
});
}
}); |
Эти учетные данные можно получить в объекте handshake на стороне сервера:
io.use((socket, next) => {
const token = socket.handshake.auth.token;
// ...
}); |
Обработка ошибки среднего сервиса
Если метод next вызывается с объектом Error, подключение будет отклонено, и клиент получит событие connect_error.
// client-side
socket.on("connect_error", (err) => {
console.log(err.message); // prints the message associated with the error
}); |
Вы можете добавить дополнительные детали к объекту Error:
// server-side
io.use((socket, next) => {
const err = new Error("not authorized");
err.data = { content: "Please retry later" }; // additional details
next(err);
});
// client-side
socket.on("connect_error", (err) => {
console.log(err instanceof Error); // true
console.log(err.message); // not authorized
console.log(err.data); // { content: "Please retry later" }
}); |
Совместимость со средними сервисами Express
Большинство существующих модулей средних сервисов Express должны быть совместимы с Socket.IO, вам просто нужна небольшая обертка, чтобы сделать соответствие методов:
const wrap = middleware => (socket, next) => middleware(socket.request, {}, next); |
Функции среднего сервиса, которые завершают цикл запроса-ответа и не вызывают next(), не будут работать.
Пример с express-session:
const session = require("express-session");
io.use(wrap(session({ secret: "cats" })));
io.on("connection", (socket) => {
const session = socket.request.session;
}); |
Пример с Passport:
const session = require("express-session");
const passport = require("passport");
io.use(wrap(session({ secret: "cats" })));
io.use(wrap(passport.initialize()));
io.use(wrap(passport.session()));
io.use((socket, next) => {
if (socket.request.user) {
next();
} else {
next(new Error("unauthorized"))
}
}); |
Полный пример с Passport можно найти здесь.
© 2014–2021 Automattic
Licensed under the MIT License.
https://socket.io/docs/v3/middlewares