Django Graphql Auth未登录用户

问题描述

我在我的 api 中使用了 Django Graphql Auth,但是当我想获取当前登录用户时,总是获取匿名。

# settings.py

MIDDLEWARE = [
    # ...
    'django.contrib.auth.middleware.AuthenticationMiddleware',# ...
]

AUTH_USER_MODEL = 'base.User'

AUTHENTICATION_BACKENDS = [
    # 'graphql_jwt.backends.JSONWebTokenBackend','graphql_auth.backends.GraphQLAuthBackend','django.contrib.auth.backends.ModelBackend',]
GRAPHENE = {
    'SCHEMA_INDENT': 4,'SCHEMA': 'byt.schema.schema','MIDDLEWARE': [
        'graphql_jwt.middleware.JSONWebTokenMiddleware','graphene_django_extras.ExtraGraphQLDirectiveMiddleware'
    ]
}

GRAPHQL_AUTH = {
    'LOGIN_ALLOWED_FIELDS': ['email','username'],# ...
}
GRAPHQL_JWT = {
    'JWT_VERIFY_EXPIRATION': True,'JWT_LONG_RUNNING_REFRESH_TOKEN': True,'ALLOW_LOGIN_NOT_VERIFIED': True,'JWT_ALLOW_ARGUMENT': True,"JWT_ALLOW_ANY_CLASSES": [
        "graphql_auth.mutations.Register","graphql_auth.mutations.VerifyAccount","graphql_auth.mutations.ResendActivationEmail","graphql_auth.mutations.SendPasswordResetEmail","graphql_auth.mutations.PasswordReset","graphql_auth.mutations.ObtainjsONWebToken","graphql_auth.mutations.VerifyToken","graphql_auth.mutations.RefreshToken","graphql_auth.mutations.Revoketoken","graphql_auth.mutations.VerifySecondaryEmail",],}
EMAIL_BACKEND = 'sendgrid_backend.SendgridBackend'
# custom user model 

class User(AbstractUser):
    ROLES = (
        ('ADMIN','ADMIN'),('USER','USER'),('BUSInesS','BUSInesS'),('TALENT','TALENT')
    )
    first_name = models.CharField(max_length=254,default="John")
    last_name = models.CharField(max_length=254,default="Doe")
    email = models.EmailField(
        blank=False,max_length=254,verbose_name="email address")
    role = models.CharField(max_length=8,choices=ROLES,default="USER")

    USERNAME_FIELD = "username"  # e.g: "username","email"
    EMAIL_FIELD = "email"  # e.g: "email","primary_email"

    def __str__(self):
        return self.username

# schema user
import graphene
from graphene_django import DjangoObjectType
from graphql_auth import mutations
from graphql_auth.schema import UserQuery,MeQuery


class AuthMutation(graphene.ObjectType):
    register = mutations.Register.Field()
    verify_account = mutations.VerifyAccount.Field()
    resend_activation_email = mutations.ResendActivationEmail.Field()
    send_password_reset_email = mutations.SendPasswordResetEmail.Field()
    password_reset = mutations.PasswordReset.Field()
    password_change = mutations.PasswordChange.Field()
    archive_account = mutations.ArchiveAccount.Field()
    delete_account = mutations.DeleteAccount.Field()
    update_account = mutations.UpdateAccount.Field()
    send_secondary_email_activation = mutations.SendSecondaryEmailActivation.Field()
    verify_secondary_email = mutations.VerifySecondaryEmail.Field()
    swap_emails = mutations.SwapEmails.Field()

    # django-graphql-jwt inheritances
    token_auth = mutations.ObtainjsONWebToken.Field()
    verify_token = mutations.VerifyToken.Field()
    refresh_token = mutations.RefreshToken.Field()
    revoke_token = mutations.Revoketoken.Field()


class Query(UserQuery,MeQuery,graphene.ObjectType):
    pass


class Mutation(AuthMutation,graphene.ObjectType):
    pass

突变 tokenAuth 返回一个有效的令牌,但是当我尝试在标头中使用该令牌执行“我”查询时,查询返回 null,因为 info.context.user 是匿名的。

我错过了什么?

解决方法

你是如何传递不记名令牌的? graphql_auth 使用“JWT”而不是“Bearer”作为令牌前缀。

,

您缺少的是 JWT 不会登录仅进行身份验证的用户。即,它只验证用户名和密码是否有效。

因此,由于 info.context.user,您无法运行 me 查询,如果您将其删除,它将运行。

要返回登录用户,首先必须使用以下方法登录:

    from django.contrib.auth import authenticate,login

    class UserType(DjangoObjectType):
        class Meta:
            model = YourUserModel

    class Query(ObjectType):
        ...
        me = graphene.Field(UserType)

        def resolve_me(self,info,**kwargs):
            username = kwargs.get('username')
            password = kwargs.get('password')
            user = authenticate(username=username,password=password)
            login(user)
            if user.is_anonymous:
                raise Exception('Authentication Failure!')
            return YourUserModel.objects.get(pk=info.context.user)

注意:检查 DOC