如何结合突变在 django-graphql-jwt 中创建或登录用户?
Posted
技术标签:
【中文标题】如何结合突变在 django-graphql-jwt 中创建或登录用户?【英文标题】:How to combine mutations to create or login user in django-graphql-jwt? 【发布时间】:2018-08-22 10:55:49 【问题描述】:我使用 VueJS 和 Django + django-graphql-jwt(返回令牌)。我想使用电子邮件\密码字段进行注册和登录。在服务器上,我想检查提供的电子邮件是否已经存在 -> 使用 django-graphql-jwt
的突变 token_auth = graphql_jwt.ObtainJSONWebToken.Field()
返回令牌 + 消息,否则 -> 使用提供的电子邮件和密码创建一个新用户并返回此用户 + 消息。
现在我有:
# schema.py
import graphene
import graphql_jwt
from django.contrib.auth import get_user_model
from graphene_django import DjangoObjectType
class UserType(DjangoObjectType):
class Meta:
model = get_user_model()
class CreateUser(graphene.Mutation):
user = graphene.Field(UserType)
class Arguments:
password = graphene.String(required=True)
email = graphene.String(required=True)
def mutate(self, info, password, email):
user = get_user_model()(
username=email.split('@')[0],
email=email,
)
user.set_password(password)
user.save()
return CreateUser(user=user)
# Want to combine two mutations here
class GetOrCreateUser(graphene.Mutation):
user = graphene.Field(UserType)
class Arguments:
password = graphene.String(required=True)
email = graphene.String(required=True)
def mutate(self, info, password, email):
# Return token
if get_user_model().objects.filter(email=email).exists():
# Just an idea, what I want to get here (to be returned to VueJS)
return 'token': graphql_jwt.ObtainJSONWebToken.Field(), 'msg': 'Token Generated'
# Create new user
else:
user = CreateUser(???)
return 'user': user, 'msg': 'User is Created'
class Mutation(graphene.ObjectType):
create_user = CreateUser.Field()
get_or_create_user = GetOrCreateUser.Field()
我尝试了不同的变体,但似乎我不完全了解图形的工作流程或\以及Graphene
的魔力(其文档没有提供信息)。
谁能告诉我,我如何在 if\else 块中重复使用已创建的代码(CreateUser
类和graphql_jwt.ObtainJSONWebToken.Field()
)?
【问题讨论】:
【参考方案1】:您可以创建一个函数并在两个突变中使用它:
def get_or_create_user(password, email):
if get_user_model().objects.filter(email=email).exists():
return ('user or token or other data that you need in'
'mutation, this is not mutation return value')
# 'token': graphql_jwt.ObtainJSONWebToken.Field(),
# 'msg': 'Token Generated'
# Create new user
else:
user = get_user_model()(
username=email.split('@')[0],
email=email,
)
user.set_password(password)
user.save()
return ('user or token or other data that you need in'
'mutation, this is not mutation return value')
# 'user': user,
# 'msg': 'User is Created'
【讨论】:
它不会像石墨烯那样工作。 1)graphql_jwt.ObtainJSONWebToken.Field()
不返回值(不返回字符串),它返回对象。 2)据我了解,返回项目的类型必须与class GetOrCreateUser(graphene.Mutation):
下声明的相同,但我不知道dict
应该使用哪种类型。
@TitanFighter 我刚刚复制了你的代码。这个函数的目的是 - 结合你的两个突变的 if/else 逻辑......【参考方案2】:
我没有找到如何从突变中调用突变(如何从class GetOrCreateUser
调用class CreateUser
,因此我决定将CreateUser
整合到GetOrCreateUser
。
我没有找到,如何通过类似代码调用graphql_jwt
(示例取自graphene doc)
schema = graphene.Schema(...)
result = schema.execute(' name ')
所以我决定直接通过 Python 而不是 Python\GraphQL 获取令牌。
以下是完整代码:
# schema.py (the root one)
import graphene
import graphql_jwt
import apps.users.schema
class Query(apps.users.schema.Query, graphene.ObjectType):
pass
class Mutation(apps.users.schema.Mutation, graphene.ObjectType):
verify_token = graphql_jwt.Verify.Field()
refresh_token = graphql_jwt.Refresh.Field()
schema = graphene.Schema(query=Query, mutation=Mutation)
和
# users/schema.py
import graphene
from django.contrib.auth import get_user_model
from graphene_django import DjangoObjectType
from graphql_jwt.shortcuts import get_token
class UserType(DjangoObjectType):
class Meta:
model = get_user_model()
class GetOrCreateUser(graphene.Mutation):
"""
mutation
getOrCreateUser(email: "test@domain.com", password: "YourPass")
token
user
id
email
isActive
"""
user = graphene.Field(UserType)
token = graphene.String()
class Arguments:
password = graphene.String(required=True)
email = graphene.String(required=True)
def mutate(self, info, password, email):
token = ''
# Return token
if get_user_model().objects.filter(email=email).exists():
user = get_user_model().objects.get(email=email)
token = get_token(user)
# Create new user
else:
user = get_user_model()(
username=email.split('@')[0],
email=email,
)
user.set_password(password)
user.save()
return GetOrCreateUser(user=user, token=token)
class Query(graphene.ObjectType):
users = graphene.List(UserType)
def resolve_users(self, info):
return get_user_model().objects.all()
FrontEnd 可以通过检查token
字段来定义状态。如果为空,则创建用户,如果有内容,则用户存在并刚刚登录。
【讨论】:
【参考方案3】:django-graphql-auth 完全符合您的要求。
它扩展了 django-graphql-jwt 以处理所有与用户帐户相关的操作。
这是来自docs的注册突变:
mutation
register(
email:"skywalker@email.com",
username:"skywalker",
password1: "supersecretpassword",
password2:"supersecretpassword"
)
success,
errors,
token,
refreshToken
它已经从 django-graphql-jwt 返回了令牌和刷新令牌。
比你可以用来登录的,来自docs:
mutation
tokenAuth(
# username or email
email: "skywalker@email.com"
password: "supersecretpassword"
)
success,
errors,
token,
refreshToken,
unarchiving,
user
id,
username
PS:我是作者
【讨论】:
以上是关于如何结合突变在 django-graphql-jwt 中创建或登录用户?的主要内容,如果未能解决你的问题,请参考以下文章
将 AWS Appsync 与 AWS Neptune 结合使用
GraphQL - 如何在查询多个突变期间检索先前突变的 id