返回
Nest如何简单便捷地实现带身份验证的GraphQL订阅功能
前端
2023-10-31 02:18:47
前言
最近在用Nest+GraphQL做一个消息推送的功能,但发现相关资料真的好少,不仅官网文档没有详细介绍,社区中也少有人讨论。所以写了这个文章,希望可以帮助到有需要的人。
概述
GraphQL订阅允许客户端订阅服务器上的事件。当事件发生时,服务器会将事件数据推送到客户端。这使得客户端可以实时更新数据,而无需不断轮询服务器。
实现
1. 安装依赖
npm install @nestjs/graphql @nestjs/websockets graphql-ws socket.io
2. 创建GraphQL订阅解析器
import { Injectable } from '@nestjs/common';
import { PubSub } from 'graphql-subscriptions';
import { Message } from './message.entity';
@Injectable()
export class MessageService {
private pubSub = new PubSub();
addMessage(message: Message): Message {
this.pubSub.publish('messageAdded', { messageAdded: message });
return message;
}
async getMessages(): Promise<Message[]> {
return [];
}
}
3. 创建WebSocket网关
import { Injectable } from '@nestjs/common';
import { WebSocketGateway, SubscribeMessage, MessageBody } from '@nestjs/websockets';
import { MessageService } from './message.service';
import { Message } from './message.entity';
@WebSocketGateway()
export class MessageGateway {
constructor(private messageService: MessageService) {}
@SubscribeMessage('messageAdded')
handleMessageAdded(@MessageBody() data: Message): void {
this.messageService.addMessage(data);
}
}
4. 配置GraphQL模块
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { MessageModule } from './message.module';
@Module({
imports: [
GraphQLModule.forRoot({
typePaths: ['./**/*.graphql'],
installSubscriptionHandlers: true,
}),
MessageModule,
],
})
export class AppModule {}
5. 使用JWT进行身份验证
为了对GraphQL订阅进行身份验证,我们需要使用JWT。首先,我们需要安装@nestjs/jwt
包:
npm install @nestjs/jwt
然后,我们需要创建一个JWT服务:
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
@Injectable()
export class AuthService {
constructor(private jwtService: JwtService) {}
login(user: any): string {
const payload = { username: user.username, sub: user.id };
return this.jwtService.sign(payload);
}
}
接下来,我们需要在GraphQL模块中配置JWT服务:
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { MessageModule } from './message.module';
import { AuthService } from './auth.service';
@Module({
imports: [
GraphQLModule.forRoot({
typePaths: ['./**/*.graphql'],
installSubscriptionHandlers: true,
context: ({ req }) => ({ req }),
}),
MessageModule,
],
providers: [AuthService],
})
export class AppModule {}
最后,我们需要在WebSocket网关中添加身份验证:
import { Injectable } from '@nestjs/common';
import { WebSocketGateway, SubscribeMessage, MessageBody } from '@nestjs/websockets';
import { MessageService } from './message.service';
import { Message } from './message.entity';
import { JwtService } from '@nestjs/jwt';
@WebSocketGateway()
export class MessageGateway {
constructor(private messageService: MessageService, private jwtService: JwtService) {}
@SubscribeMessage('messageAdded')
handleMessageAdded(@MessageBody() data: Message, @Request() req: any): void {
const token = req.headers.authorization.split(' ')[1];
const payload = this.jwtService.decode(token);
if (payload && payload.username === 'admin') {
this.messageService.addMessage(data);
}
}
}
总结
以上就是如何在Nest中实现带身份验证的GraphQL订阅的方法。希望对大家有所帮助。