【问题标题】:How to send credentials with ngx-socket-io?如何使用 ngx-socket-io 发送凭据?
【发布时间】:2021-07-06 14:46:50
【问题描述】:

我需要在 Angular 中实现一个 socket.io 客户端,我找到了 ngx-socket-io。它似乎工作正常,但我没有找到在启动连接时发送凭据的选项,如官方页面所述,使用 auth > token。 (https://socket.io/docs/v4/middlewares/#Sending-credentials)

我已经实现了服务器并以这种格式工作,从socket.handshake.auth.token获取数据。

如何通过 ngx-socket-io 发送此令牌?
还有其他可以在 Angular 中使用的 socket.io 库吗?

【问题讨论】:

    标签: angular socket.io ngx-socket-io


    【解决方案1】:

    我找到了一种解决方法,在构造函数中插入空选项,然后立即添加身份验证。这并不理想,但似乎可以正常工作。我在这里分享它以防其他人需要它。

    import { AuthService } from '@my/core';
    import { Socket } from 'ngx-socket-io';
    import { environment } from 'src/environments/environment';
    
    export class MySocket extends Socket {
        constructor(
            private authService: AuthService,
        ) {
            super({ url: environment.urlSocket, options: {} });
            this.ioSocket['auth'] = { token: this.authService.token };
        }
    }
    

    【讨论】:

      【解决方案2】:

      您可以创建一个可用于启动 Socket 连接的 Injectable 服务

      import { Observable } from 'rxjs';
      import { Injectable } from '@angular/core';
      import { Socket } from 'ngx-socket-io';
      import { AuthenticationService } from '@app/auth/services/authentication.service';
      
      @Injectable({
        providedIn: 'root'
      })
      export class WebSocketService {
        constructor(private socket: Socket, private authenticationService: AuthenticationService) {
          const currentUser = this.authenticationService.currentUserValue;
          this.socket.ioSocket.io.opts.query = { Authorization: `${currentUser.accessToken}` };
        }
      
        public sendMessage(event, message) {
          this.socket.emit(event, message);
        }
      
        public getMessage(eventName) {
          return new Observable(observer => {
            this.socket.on(eventName, message => {
              observer.next(message);
            });
          });
        }
      }
      

      在你的组件中,你可以注入你的服务:

      import { WebSocketService } from './web-socket.service';
      
      @Component({
        selector: 'app-conversation',
        templateUrl: './conversation.component.html',
        styleUrls: ['./conversation.component.scss']
      })
      export class MyComponent implements OnInit {
        constructor( private webSocket: WebSocketService) {}
        
        ngOnInit() {
          this.webSocket.getMessage('testing').subscribe(msg => console.log(msg));
         }
      }
      

      在您的服务器中,收到令牌

      handleConnection(socket: Socket) {
      const token  = socket.handshake.query.Authorization;
      

      【讨论】:

      • 您的建议并没有解决我的问题,因为它需要使用“查询”发送的参数,而不是使用 Socket.io 身份验证标准。这样我就不得不改变我试图避免的服务器。我用我找到的解决方案添加了答案。