fullstack GraphQL学习笔记(13)认证
1、django内置了用户的管理
在hackersnews下创建一个users文件夹并在该文件夹下创建一个schema.py
from django.contrib.auth import get_user_model
import graphene
from graphene_django import DjangoObjectType
class UserType(DjangoObjectType):
class Meta:
model = get_user_model()
class CreateUser(graphene.Mutation):
user = graphene.Field(UserType)
class Arguments:
username = graphene.String(required=True)
password = graphene.String(required=True)
email = graphene.String(required=True)
def mutate(self, info, username, password, email):
user = get_user_model()(
username=username,
email=email,
)
user.set_password(password)
user.save()
return CreateUser(user=user)
class Mutation(graphene.ObjectType):
create_user = CreateUser.Field()
这里可以看到我们并没有像createLink那样把所有的字段列出来,而是使用了user = graphene.Field(UserType),以返回整个user.
在settings.py中注册app users
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'graphene_django',
'links',
'users',
]
下面把User的schema放在根schema下
import graphene
import links.schema
import users.schema
class Query(links.schema.Query, graphene.ObjectType):
pass
class Mutation(users.schema.Mutation,links.schema.Mutation, graphene.ObjectType):
pass
schema = graphene.Schema(query=Query,mutation=Mutation)
现在我们可以执行mutation操作了。
mutation{
createUser(
username:"adcers",
password:"123345ddd",
email:"adcers@124.com"
){
user{
username
email
}
}
}
下面创建查询用户,在user/schema.py
class Query(graphene.ObjectType):
users = graphene.List(UserType)
def resolve_users(self, info):
return get_user_model().objects.all()
在hackernews/schema.py增加
class Query(users.schema.Query, links.schema.Query, graphene.ObjectType):
pass
这样我们便可以查询了
query{
users{
id
username
email
}
}
2、用户认证
django内置了用户认证的内容,使用session在服务端保存临时数据,是一种有状态的服务。今天多数的服务都是无状态的,即一次请求没有任何依赖。我们将使用django-graphql-jwt库在Graphene中实现JWT令牌。当用户注册或登录时,将返回令牌:识别用户身份的一段数据。用户以后再次访问需要认证的站点时必须把token放在http头部以便于验证。遗憾的是,我们之前使用的GraphiQL Web界面不接受添加自定义HTTP标头。从现在开始,我们将使用Insomnia桌面应用程序。您可以在此处下载并安装它。
配置django-graphql-jwt
在settings.py的中间件中增加
'graphql_jwt.middleware.JSONWebTokenMiddleware',
另外在settings.py中新增设置:
AUTHENTICATION_BACKENDS = [
'graphql_jwt.backends.JSONWebTokenBackend',
'django.contrib.auth.backends.ModelBackend',
]
在hackernews中使用该库,修改Mutation
import graphql_jwt
class Mutation(users.schema.Mutation,links.schema.Mutation, graphene.ObjectType):
token_auth = graphql_jwt.ObtainJSONWebToken.Field()
verify_token = graphql_jwt.Verify.Field()
refresh_token = graphql_jwt.Refresh.Field()
该库为我们创建了三个Mutaitions:
token_auth:接受用户名和密码,生成token
verfiy:接受token作为参数,验证token是否有效
refresh:在令牌未过期的更新到期时间内获取新令牌(如果它们已启用到期).
除此之外,可以在库上配置Mutations和JWT的各个方面.请查看文档以获取更多信息。
mutation{
tokenAuth(
username:"22323"
password:"adfasdfa"
){
token
}
}
返回结果:
{
"data": {
"tokenAuth": {
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImxpdHVmdSIsImV4cCI6MTUzNTUxNDAxNSwib3JpZ19pYXQiOjE1MzU1MTM3MTV9.7AawmYv4F4OjYCPswpjrPDt_phf4BhZNFtvkuTxVfp8"
}
}
}
验证token
mutation{
verifyToken(token:"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImxpdHVmdSIsImV4cCI6MTUzNTUxNDAxNSwib3JpZ19pYXQiOjE1MzU1MTM3MTV9.7AawmYv4F4OjYCPswpjrPDt_phf4BhZNFtvkuTxVfp8"){
payload
}
}
返回结果:
{
"data": {
"verifyToken": {
"payload": {
"username": "22323", "exp": 1535514015, "orig_iat": 1535513715 } } } }
测试身份验证
为了测试我们的身份验证是否正常工作,让我们创建一个名为Query的查询me,如果登录则应该返回用户的信息,否则返回错误。
修改users/schema.py
class Query(graphene.ObjectType):
users = graphene.List(UserType)
me = graphene.Field(UserType)
def resolve_users(self, info):
return get_user_model().objects.all()
def resolve_me(self, info):
user = info.context.user
if user.is_anonymous:
raise Exception('Not logged!')
return user
为了测试它,我们需要使用tokenAuth Mutation 获取一个token,并在HTTP头部设置AUTHORIZATION:使用前缀JWT+token。现在,我们要去Inmsonia客户端:
query{
me{
id
username
}
}
便可以查询到需要的信息。
浙公网安备 33010602011771号