繁体   English   中英

使用 websockets 和 Nest.js 的 Passport 会话身份验证未进行身份验证

[英]Passport session authentication with websockets and Nest.js not authenticating

我无法使用 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;
  }
}

事件网关.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]
    }

我有同样的问题,问题是,在你的 WS Authenticated 守卫中,没有 request.isAuthenticated() 函数。 至少在我的情况下。

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

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

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

app.useWebSocketAdapter(new SessionAdapter(sessionMiddleware));

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM