socket.io - NestJs Socket io 适配器:如果使用 false 调用 allowFunction,服务器不会将 CORS 标头添加到握手的响应中。错误或配置错误?
问题描述
经过身份验证的套接字 io.adapter.ts
export class AuthenticatedSocketIoAdapter extends IoAdapter {
private readonly authService: AuthService;
constructor(private app: INestApplicationContext) {
super(app);
this.authService = this.app.get(AuthService);
}
createIOServer(port: number, options?: SocketIO.ServerOptions): any {
options.allowRequest = async (request, allowFunction) => {
const { authorized, errorMessage } = await this.check(parse(request?.headers?.cookie || '').jwt, [UserRole.ADMIN]);
if (!authorized) {
return allowFunction(errorMessage, false);
}
return allowFunction(null, true);
};
return super.createIOServer(port, options);
}
main.ts
const app = await NestFactory.create(AppModule);
app.enableCors({
origin: ['http://localhost:4200'],
credentials: true
});
app.use(cookieParser());
app.use(csurf({ cookie: true }));
app.useWebSocketAdapter(new AuthenticatedSocketIoAdapter(app));
授权成功时: 授权成功
授权失败时: 授权失败
解决方案
发现问题:来自socket io的函数处理错误信息:
/**
* Sends an Engine.IO Error Message
*
* @param {http.ServerResponse} response
* @param {code} error code
* @api private
*/
function sendErrorMessage (req, res, code) {
var headers = { 'Content-Type': 'application/json' };
var isForbidden = !Server.errorMessages.hasOwnProperty(code);
if (isForbidden) {
res.writeHead(403, headers);
res.end(JSON.stringify({
code: Server.errors.FORBIDDEN,
message: code || Server.errorMessages[Server.errors.FORBIDDEN]
}));
return;
}
if (req.headers.origin) {
headers['Access-Control-Allow-Credentials'] = 'true';
headers['Access-Control-Allow-Origin'] = req.headers.origin;
} else {
headers['Access-Control-Allow-Origin'] = '*';
}
if (res !== undefined) {
res.writeHead(400, headers);
res.end(JSON.stringify({
code: code,
message: Server.errorMessages[code]
}));
}
}
这里的“code”参数将是我在这里传入的参数“allowFunction( errorMessage , false)”该值必须是“0”、“1”、“2”、“3”或“4”之一,否则isForbidden 将为 false,因此不设置“Access-Control-Allow-Credentials”标头。
Server.errorMessages = {
0: 'Transport unknown',
1: 'Session ID unknown',
2: 'Bad handshake method',
3: 'Bad request',
4: 'Forbidden'
};
希望有一天这对某人有所帮助。