[英]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.