【问题标题】:Passport session authentication with websockets and Nest.js not authenticating使用 websockets 和 Nest.js 的 Passport 会话身份验证未进行身份验证
【发布时间】:2021-10-11 12:24:07
【问题描述】:

我无法使用 socket.io 和 nest.js 获得会话身份验证。在常规请求中,会话警卫工作得很好。适配器本身似乎工作。控制台没有显示错误,只是没有进行身份验证。

main.ts

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const configService = app.get(ConfigService);
  const sessionSecret = configService.get('SESSION_SECRET');
  const MongoUri = configService.get('MONGO_URI');
  const sessionMiddleware = session({
    secret: sessionSecret,
    resave: false,
    saveUninitialized: false,
    store: MongoStore.create({ mongoUrl: MongoUri }),
    cookie: {
      maxAge: 60 * 1000 * 60 * 24 * 14,
    },
  });
  app.enableCors({
    origin: 'http://localhost:4200',
    credentials: true,
  });
  app.use(sessionMiddleware);
  app.use(passport.initialize());
  app.use(passport.session());
  app.use(cookieParser());
  app.useWebSocketAdapter(new SessionAdapter(sessionMiddleware));
  await app.listen(3000);
}
bootstrap();

会话适配器

export class SessionAdapter extends IoAdapter {
  private session: express.RequestHandler;

  constructor(session: express.RequestHandler) {
    super(session);
    this.session = session;
  }

  create(port: number, options?: ServerOptions): Server {
    const server: Server = super.create(port, options);

    const wrap = (middleware) => (socket, next) =>
      middleware(socket.request, {}, next);

    server.use((socket, next) => {
      socket.data.username = 'test'; //passing random property to see if use method is working
      next();
    });
    server.use(wrap(this.session));
    server.use(wrap(passport.initialize()));
    server.use(wrap(passport.session()));
    return server;
  }
}

Event.gateway.ts

@WebSocketGateway(80, {
  cors: {
    origin: 'http://localhost:4200',
  },
})
export class EventsGateway implements OnGatewayConnection {
  @WebSocketServer()
  server: Server;

  // @UseGuards(AuthenticatedGuard)
  @UseGuards(WsAuthenticatedGuard)
  @SubscribeMessage('message')
  handleMessage(client: any, payload: any): string {
    console.log(payload);
    console.log(client.username);
    console.log(client.request.user);
    client.emit('answer', 'Hello client');
    return payload;
  }

  handleConnection(client: any, ...args: any[]) {
    console.log(client.data.username); //console is showing 'test' as it suppose to
    console.log('user connected');
  }
}

ws.authenticated.guard.ts

@Injectable()
export class WsAuthenticatedGuard implements CanActivate {
  async canActivate(context: ExecutionContext) {
    const client = context.switchToWs().getClient();
    const request = client.request;
    console.log(request.isAuthenticated());
    return request.isAuthenticated(); //guard returns false
  }
}

authenticated.guard.ts(常规请求的保护)

@Injectable()
export class AuthenticatedGuard implements CanActivate {
  async canActivate(context: ExecutionContext) {
    const request = context.switchToHttp().getRequest();
    return request.isAuthenticated();
  }
}

控制台记录的请求显示会话和护照已初始化,但没有来自 passport.session() 的用户属性

sessionID: 'Mu7DiHk_eNZ4S-ujFhnXOOqOl7EwLLFe',
  session: Session {
    cookie: {
      path: '/',
      _expires: 2021-08-21T15:53:24.871Z,
      originalMaxAge: 1209600000,
      httpOnly: true
    }
  },
  _passport: {
    instance: Authenticator {
      _key: 'passport',
      _strategies: [Object],
      _serializers: [Array],
      _deserializers: [Array],
      _infoTransformers: [],
      _framework: [Object],
      _userProperty: 'user',
      _sm: [SessionManager],
      Authenticator: [Function: Authenticator],
      Passport: [Function: Authenticator],
      Strategy: [Function],
      strategies: [Object]
    }

【问题讨论】:

    标签: node.js passport.js nestjs


    【解决方案1】:

    看来您必须将app 传递给IoAdapter 的构造函数:

    constructor(session: express.RequestHandler, app: INestApplicationContext) {
      super(app);
      this.session = session;
    }
    

    并按如下方式初始化适配器:

    app.useWebSocketAdapter(new SessionAdapter(sessionMiddleware));
    

    至少在我的情况下,这是缺少的部分。

    【讨论】:

      猜你喜欢
      • 2015-05-18
      • 2016-08-15
      • 2015-09-23
      • 2013-12-29
      • 1970-01-01
      • 2019-10-04
      • 1970-01-01
      • 1970-01-01
      • 2011-02-11
      相关资源
      最近更新 更多