django - 如何将 Django HTTP 登录会话与 Websocket 会话/Cookie 同步?
问题描述
我正在使用 Django DjangoChannelsGraphqlWs,它是 Django Channels 的石墨烯版本。( https://github.com/datadvance/DjangoChannelsGraphqlWs ) 它允许我使用 graphql 样式传输数据。我在我的变异模式上写了一个登录登录。
class Login(graphene.Mutation):
class Arguments:
email = graphene.String()
password = graphene.String()
ok = graphene.Boolean()
user = graphene.Field(UserType)
def mutate(root, info, email, password, **kwargs):
ok = False
user = authenticate(info.context, username=email, password=password)
if user is not None:
login(info.context, user)
update_or_create_user_login_info(info=info)
ok = True
return Login(ok=ok, user=user)
else:
return Login(ok=ok)
我使用 Apollo-client 编写了我的客户端 Websocket,如下所示:
class WebSocketService {
static instance = null;
callbacks = {};
static getInstance() {
if (!WebSocketService.instance)
WebSocketService.instance = new WebSocketService();
return WebSocketService.instance;
}
constructor() {
this.socketRef = null;
this.connect();
}
connect() {
const client = new SubscriptionClient(BASE_URL + '/graphql/', {
reconnect: true,
});
const link = new WebSocketLink(client);
const cache = new InMemoryCache();
this.socketRef = new ApolloClient({
link,
cache,
});
}
query = (query, variables={}, context={}, fetchPolicy='no-cache', errorPolicy='all') =>
this.socketRef.query({
query: gql`${query}`,
variables,
context,
fetchPolicy,
errorPolicy
})
mutate = (mutation, variables={}, context={}, fetchPolicy='no-cache', errorPolicy='all') =>
this.socketRef.mutate({
mutation: gql`${mutation}`,
variables,
context,
fetchPolicy,
errorPolicy
})
}
const WebSocketInstance = WebSocketService.getInstance();
export default WebSocketInstance;
最后,这是我的消费者。
class MyGraphqlWsConsumer(channels_graphql_ws.GraphqlWsConsumer):
"""Channels WebSocket consumer which provides GraphQL API."""
schema = schema
send_keepalive_every = 60
我尝试使用 WebSocketInstance 登录。但是,当我交出 info.context 和 authenticate(info.context, user) 参数时,Django 的登录功能会失败。它抛出错误说“types.SimpleNamespace'对象没有属性'META'”。在偶然发现错误之后,我放弃了使用 websocket 登录,并决定只使用 axios 和普通的 http 请求。
但这是另一个问题。会话和 cookie 未同步。当我使用 axios 和正常的 http 请求时,登录本身运行良好,但 websocket 连接不反映登录的会话/cookies。
我发现反映更改需要一些时间,并且在断开并重新连接 websocket 后发生。
我应该如何同步登录信息?
解决方案
尝试覆盖 graphl_jwt
class ObtainJSONWebToken(graphql_jwt.JSONWebTokenMutation):
user = graphene.Field(UserType)
session = graphene.String()
@classmethod
def resolve(cls, root, info, **kwargs):
user=info.context.user
if user:
login(info.context,user)
session=info.context.session
session.save()
if session.session_key:
#print(session.session_key)
return cls(user=user,session=session.session_key)
else:
raise Exception('try it again')
突变中
class Mutation(graphene.ObjectType):
token_auth=ObtainJSONWebToken.Field()
推荐阅读
- javascript - 按数据属性中匹配的关键字对列表进行排序
- java - OOP 我如何将被击败的敌人的钱添加到主角的包中?
- flutter - Flutter:如何从设备中读取 ImagePicker 包的图像
- java - J2SE 得到一个抛出异常 451 的 json 响应?
- flutter - 网页颤动:在显示之前从 NetworkImage 获取宽度/高度
- oracle - Spring Data JPA:当一个表本身是另一个多对多关系的连接表时,两个表之间的多对多映射
- bash - Redis 公钥
- snowflake-cloud-data-platform - Clustering, does sorting data before injestion improve performance of truncating my table?
- pandas - 根据子网的值(在不同的列上)将 IP 地址增加 1
- javascript - 使用 Javascript 和 JQuery 创建过滤器按钮