Code Monkey home page Code Monkey logo

django-graphql-social-auth's Introduction

Django GraphQL Social Auth

Pypi Wheel Build Status Codecov Code Climate

Python Social Auth support for Django GraphQL

Dependencies

  • Python ≥ 3.4
  • Django ≥ 1.11

Installation

Install last stable version from Pypi.

pip install django-graphql-social-auth

See the documentation for further guidance on setting Python Social Auth.

Add the SocialAuth mutation to your GraphQL schema.

import graphene
import graphql_social_auth


class Mutations(graphene.ObjectType):
    social_auth = graphql_social_auth.SocialAuth.Field()

Session authentication via accessToken.

  • provider: provider name from Authentication backend list.
  • accessToken: third-party (Google, Facebook...) OAuth token obtained with any OAuth client.
mutation SocialAuth($provider: String!, $accessToken: String!) {
  socialAuth(provider: $provider, accessToken: $accessToken) {
    social {
      uid
      extraData
    }
  }
}

JSON Web Token (JWT)

Authentication solution based on JSON Web Token.

Install additional requirements.

pip install 'django-graphql-social-auth[jwt]'

Add the SocialAuthJWT mutation to your GraphQL schema.

import graphene
import graphql_social_auth


class Mutations(graphene.ObjectType):
    social_auth = graphql_social_auth.SocialAuthJWT.Field()

Authenticate via accessToken to obtain a JSON Web Token.

mutation SocialAuth($provider: String!, $accessToken: String!) {
  socialAuth(provider: $provider, accessToken: $accessToken) {
    social {
      uid
    }
    token
  }
}

Relay

Complete support for Relay.

import graphene
import graphql_social_auth


class Mutations(graphene.ObjectType):
    social_auth = graphql_social_auth.relay.SocialAuth.Field()

graphql_social_auth.relay.SocialAuthJWT.Field() for JSON Web Token (JWT) authentication.

Relay mutations only accepts one argument named input:

mutation SocialAuth($provider: String!, $accessToken: String!) {
  socialAuth(input:{provider: $provider, accessToken: $accessToken}) {
    social {
      uid
    }
  }
}

Customizing

If you want to customize the SocialAuth behavior, you'll need to customize the resolve() method on a subclass of SocialAuthMutation or .relay.SocialAuthMutation.

import graphene
import graphql_social_auth


class SocialAuth(graphql_social_auth.SocialAuthMutation):
    user = graphene.Field(UserType)

    @classmethod
    def resolve(cls, root, info, social, **kwargs):
        return cls(user=social.user)

Authenticate via accessToken to obtain the user id.

mutation SocialAuth($provider: String!, $accessToken: String!) {
  socialAuth(provider: $provider, accessToken: $accessToken) {
    social {
      uid
    }
    user {
      id
    }
  }
}

Project template

There is a Django project template to start a demo project.


Gracias @omab / Python Social Auth.

django-graphql-social-auth's People

Contributors

eoin-obrien avatar mongkok avatar pidelport avatar syrusakbary avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-graphql-social-auth's Issues

Option to set cookie

Please add the set_cookie_auth to social mutation also for setting cookie and refresh_token

Oauth requests from the backend server

Hey I was just thinking that rather than using the frontend to send the access token what if the access token stored in the backend is used to make the request to the Oauth server.

I think I should explain what I was trying to do here... I have a project built using django and I recently created a graphql API using django graphene. originally the project had python social auth and was using it to login thru google using the secrets stored in the backends' .env file.

now since I have the grqphql API in place I want to just use a mutation to take the provider as an argument from my frontend and then the backend using the keys stored in the .env file make all the network calls, like exchanging auth code for token etc., to the Oauth2.0 auth server and resource server to get back a JWT token (in my case I am using JWT tokens for auth) and then that mutation will return a response just like this project does.

django social auth don't associate new users correctly

I am trying to use social auth in Django in my Django GraphQL API (an alternative to rest api). However, after I created the social auth I created a costume user which make things a bit complicated. Also, it worked at the begging very well but and it created the user called weplutus.1 very well, but later after I added the following settings

#settings.py
#without this code i will get `anonymouseUser`
GRAPHENE = {
    # 'SCHEMA': 'api.schema.schema',
    'MIDDLEWARE': [
        # the problem is here
        'graphql_jwt.middleware.JSONWebTokenMiddleware',
    ],
}

when new users register the social auth associate it with other an existed user even the email is new.

enter image description here

# settings.py

from pathlib import Path
import os

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '*****'


DEBUG = True

ALLOWED_HOSTS = ["*"]  # TODO change this in preduction

CORS_ORIGIN_ALLOW_ALL = True  # TODO change this in preduction

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'graphene_django',
    'corsheaders',
    'api',
    'django_filters',
    'social_django',
]
SITE_ID = 1
MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

GRAPHENE = {
    # Note without this you will get anynomus user.
    'MIDDLEWARE': [
        'graphql_jwt.middleware.JSONWebTokenMiddleware',
    ],
}


AUTH_USER_MODEL = 'api.ExtendUser'


# TODO delete this, test if thes send email when creating a new user
# if so try to stop it.
# EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'


ROOT_URLCONF = 'django_graphql.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'django_graphql.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases

DATABASES = {
    'default': {
        # When using PostgreSQL, it’s recommended to use the built-in JSONB field (# SOCIAL_AUTH_POSTGRES_JSONFIELD = True) to store the extracted extra_data. To enable it define the setting:
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}
# SOCIAL_AUTH_POSTGRES_JSONFIELD = True

SOCIAL_AUTH_JSONFIELD_ENABLED = True


# Password validation
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# AUTHENTICATION_BACKENDS can be found here http://docs.djangoproject.com/en/dev/ref/settings/?from=olddocs#authentication-backends

AUTHENTICATION_BACKENDS = [
    'graphql_jwt.backends.JSONWebTokenBackend',
    # provider google-oauth2
    'social_core.backends.google.GoogleOAuth2',
    # 'graphql_auth.backends.GraphQLAuthBackend',
    'django.contrib.auth.backends.ModelBackend',
]

SOCIAL_AUTH_PIPELINE = [
    # Get the information we can about the user and return it in a simple
    # format to create the user instance later. On some cases the details are
    # already part of the auth response from the provider, but sometimes this
    # could hit a provider API.
    'social_core.pipeline.social_auth.social_details',

    # Get the social uid from whichever service we're authing thru. The uid is
    # the unique identifier of the given user in the provider.
    'social_core.pipeline.social_auth.social_uid',

    # Verifies that the current auth process is valid within the current
    # project, this is where emails and domains whitelists are applied (if
    # defined).
    'social_core.pipeline.social_auth.auth_allowed',

    # Checks if the current social-account is already associated in the site.
    'social_core.pipeline.social_auth.social_user',

    # Make up a username for this person, appends a random string at the end if
    # there's any collision.
    'social_core.pipeline.user.get_username',

    # Send a validation email to the user to verify its email address.
    # Disabled by default.
    # 'social_core.pipeline.mail.mail_validation',

    # Associates the current social details with another user account with
    # a similar email address. Disabled by default.
    'social_core.pipeline.social_auth.associate_by_email',

    # Create a user account if we haven't found one yet.
    'social_core.pipeline.user.create_user',

    # Create the record that associates the social account with the user.
    'social_core.pipeline.social_auth.associate_user',

    # Populate the extra_data field in the social record with the values
    # specified by settings (and the default ones like access_token, etc).
    'social_core.pipeline.social_auth.load_extra_data',

    # Update the user record with any changed info from the auth service.
    'social_core.pipeline.user.user_details',
]

SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = "*******"

SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = "*********"

# Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/

STATIC_URL = '/static/'
MEDIA_URL = '/images/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'static/images')
AUTH_USER_MODEL = 'api.ExtendUser'
ACCOUNT_EMAIL_REQUIRED = False

#modeles.py
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User, Group, AbstractUser, AbstractBaseUser, BaseUserManager, PermissionsMixin
from django.conf import settings
from django.core.validators import RegexValidator
from django.contrib.auth import get_user_model


StyleTitleFormat = RegexValidator(r'^[^\s]+$', 'spaces not allowed')
# Create your models here.


# class ExtendUser(AbstractBaseUser):
class ExtendUser(AbstractUser, PermissionsMixin):
    username = models.CharField(max_length=30, unique=True)
    email = models.EmailField(max_length=250, unique=True)
    first_name = models.CharField(max_length=30, blank=True, null=True)
    last_name = models.CharField(max_length=30, blank=True, null=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    date_joined = models.DateTimeField(default=timezone.now)
    receive_newsletter = models.BooleanField(default=False)
    birth_date = models.DateTimeField(blank=True, null=True)
    address = models.CharField(max_length=300,  blank=True, null=True)
    city = models.CharField(max_length=30, blank=True, null=True)
    about_me = models.TextField(max_length=500, blank=True, null=True)
    imageUrl = models.URLField(null=True, blank=True)

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email', ]


class Style(models.Model):
    title = models.CharField(max_length=200, validators=[StyleTitleFormat])
    description = models.CharField(max_length=9999999)
    added_by = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    created_date = models.DateTimeField(default=timezone.now)
    who_can_see = models.ManyToManyField(
        settings.AUTH_USER_MODEL, related_name='style_user', blank=True)
    who_can_edite = models.ManyToManyField(
        settings.AUTH_USER_MODEL, related_name='who_can_edite_style', blank=True)

    def __str__(self):
        return self.title


class Post(models.Model):
    # note: posts can have tables as well and they can save it in the description (JSONField)
    # title = models.CharField(max_length=200)
    description = models.CharField(max_length=9999999)
    preBuildStyle = models.ManyToManyField(
        Style, related_name='Styles', blank=True)
    style = models.CharField(max_length=9999999, blank=True)
    # type = ['Paper','post','template','comstume_component']
    postType = models.CharField(max_length=50, blank=True)
    added_by = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    created_date = models.DateTimeField(default=timezone.now)
    who_can_see = models.ManyToManyField(
        settings.AUTH_USER_MODEL, related_name='poster_user', blank=True)
    who_can_edite = models.ManyToManyField(
        settings.AUTH_USER_MODEL, related_name='who_can_edite_Component', blank=True)

    # def __str__(self):
    #     return self.title

# TODO create teams/groups/classes each with admin(creator)+manager(subAdmins)+members

README change proposition

Thank you for this repo and for JWT!!! I have been waiting for something like this for the last 2 months :)

Regarding propositions, I would add the next info to the README:

  1. provider name can be taken from this source. Then you need to go to the provider you need and find the variable called name. So, this is the exact name which must be provided to socialAuth(provider:"NAME_VAR_FROM_URL_ABOVE", accessToken:"xxxx"). For example, for Google OAuth2 it is google-oauth2 (taken from here)

  2. For those who are not good with OAuth system, accessToken must be provided by the provider (ie Google, Facebook, so on). For example, for Google we can get it in FrontEnd using such code: gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse().access_token (of course gapi js client must be uploaded first and user must let you get access to his\her data before you are able to retrieve access_token).

  3. As I mentioned in Issue #3 :

From READM it is unclear whether we need to fully replace graphql_social_auth.relay.SocialAuth.Field() by graphql_social_auth.relay.SocialAuthJWT or just the part before .Field().

So I propose to make it a bit clearer.

add a way to skip user verification

I wanted to skip the verification of newly added users. I have managed in the customized SocialAuth(GraphQL_social_auth.SocialAuthJWT) function. but the problem is the code is running every time the user is logging in or registering. add the functionality to have a setting variable for disabling the verification.

Relay mutation has errors (at least JWT version)

From READM it is unclear whether we need to fully replace graphql_social_auth.relay.SocialAuth.Field() by graphql_social_auth.relay.SocialAuthJWT or just the part before .Field(), so I tried both ways.

I tried the next code:

import graphene
import graphql_social_auth

class Mutations(graphene.ObjectType):
    # Tried this
    social_auth = graphql_social_auth.relay.SocialAuthJWT
    # and this
    social_auth = graphql_social_auth.relay.SocialAuthJWT.Field()

The first way (social_auth = graphql_social_auth.relay.SocialAuthJWT) returns:

{
    "errors": [
        {
            "message": "Cannot query field \"socialAuth\" on type \"Mutation\".",
            "locations": [
                {
                    "line": 2,
                    "column": 5
                }
            ]
        }
    ]
}

The second way (social_auth = graphql_social_auth.relay.SocialAuthJWT.Field()) returns:

{
    "errors": [
        {
            "message": "Unknown argument \"provider\" on field \"socialAuth\" of type \"Mutation\".",
            "locations": [
                {
                    "line": 2,
                    "column": 16
                }
            ]
        },
        {
            "message": "Unknown argument \"accessToken\" on field \"socialAuth\" of type \"Mutation\".",
            "locations": [
                {
                    "line": 2,
                    "column": 42
                }
            ]
        },
        {
            "message": "Field \"socialAuth\" argument \"input\" of type \"SocialAuthJWTInput!\" is required but not provided.",
            "locations": [
                {
                    "line": 2,
                    "column": 5
                }
            ]
        }
    ]
}

This query works with social_auth = graphql_social_auth.SocialAuthJWT.Field() (no relay)

How to trigger authentication with React frontend?

I'm building an app with Django, Graphene and React. I'd like to add Github OAuth login and this package seems awesome! I'm having some trouble understanding how everything wires together though. Based on the queries provided in the README it seems that my frontend will have to perform the entire OAuth flow and once it has an access token should trigger a mutation with the right provider.

What I'm hung up on is whether it's safe for my frontend to have the clientSecret which is needed for the OAuth flow. Based on the github oauth docs I can see how the first GET request from the frontend will work. I'm not sure how execute the POST with the code provided by Github to get the users access token.

Should react query the server for the clientSecret to perform the POST? Is that a security problem because anyone will be able to start a debugger, set a breakpoint just before the POST and dump the secret?

Error in the authentication with twitter

When the next mutation is made in graphql:

mutation TwitterAuthetication{
  social_auth(provider: "twitter", access_token: "1445260549-Y6i3s6luLmiJC9djgts90IuNCM09mtXfxV0zIAO")
    social
      uid
    }
    token
  }
}

gives me the following error:

{
  "errors": [
    {
      "message": "403 Customer error: Forbidden for url: https://api.twitter.com/1.1/account/verify_credentials.json?include_email=true",
      "Places": [
        {
          "line": 2,
          "Column": 3
        }
      ],
      "way": [
        "social_auth"
      ]
    }
  ],
  "data": {
    "social_auth": null
  }
}

They're following all the conventions, instead with Facebook if it works!

How can we create a username insensitive check for social login

The issue is I already done a normal email registeration with a username as pawan.
Now if some other user is doing social login and his facebook or gmail username is pawan, the new user is also getting username as "Pawan", which is a case sensitive check. But i dont dont want same usernames like "Pawan", "pawan" or "paWan". It should treat all as one and create a random username out of it.
I am using:
django-graphql-auth==0.3.16
django-graphql-jwt==0.3.0
django-graphql-social-auth==0.1.4
Django==3.2.4

socialauth

`# Middleware
MIDDLEWARE = [
"corsheaders.middleware.CorsMiddleware",

"django.middleware.cache.UpdateCacheMiddleware",

"django.middleware.security.SecurityMiddleware",

"django.contrib.sessions.middleware.SessionMiddleware",

"django.middleware.common.CommonMiddleware",

"django.middleware.csrf.CsrfViewMiddleware",

"django.contrib.auth.middleware.AuthenticationMiddleware",

"django.contrib.messages.middleware.MessageMiddleware",

"django.middleware.clickjacking.XFrameOptionsMiddleware",


"django.middleware.cache.FetchFromCacheMiddleware",

]`

Is there example of making query with received JWT token?

Hi!
In REDME there is no example or explanation how, after receiving JWT token, further requests should be authenticated.
In other repo https://django-graphql-jwt.domake.io/en/stable/authentication.html#http-header
there is example with providing header to each request with token:

POST / HTTP/1.1
Host: domake.io
Authorization: JWT <token>
Content-Type: application/json;

Is it possible to do with current package?

Also I am curious if it is possible to mix generation of token part from this repo with access decorators from django-graphql-jwt

Question: How to use an idToken rather than an accessToken?

Google's docs for Android-based OAUTH2 authentication say that we should send an idToken rather than an accessToken to our backend server.

How do you do that using Graphene Social Auth?

The only docs/examples I've found use access tokens. For instance:

mutation SocialAuth($provider: String!, $accessToken: String!) {
  socialAuth(provider: $provider, accessToken: $accessToken) {
    social {
      uid
      extraData
    }
  }
}

I imagine I can use Graphene Social Auth as is, by exchanging my idTokens for accessTokens in my Android client, but I'd rather do that server-side as Google recommends, just by sending in the idToken to the server and then have Graphene Social Auth exchange it for an accessToken and then do its stuff.

thanks!

John

when I add class Arguments: the original arguments disappeared?

I need to create the following custom class mutation , in order to create users if they are not aready exists. To do that I need to pas arguments from the forest end like username, password.....
So I tried this .

class SocialAuth(graphql_social_auth.SocialAuthJWT):
    # class Arguments:
    #     id = graphene.Int(required=False)
    user = graphene.Field(schema.Users)

    @classmethod
    def resolve(cls, root, info, social, **kwargs):
        try:
            user = models.ExtendUser.objects.get(email=social.uid)
            return cls(user=user)
        except:
            # TODO use profileObj. get username email and all these and add them kwargs
            user = models.ExtendUser.objects.create(
                email=social.uid, username=social.uid[0:6], password="AAssppmm11", imageUrl="https://miro.medium.com/max/1200/1*mk1-6aYaf_Bes1E3Imhc0A.jpeg")
            return cls(user=user)

But adding class Arguments: make the arguments provider and accessToken disappear.

an other problem is the token return null in the costum class mutation, while is working very well in the social_auth = graphql_social_auth.SocialAuthJWT.Field()

Setting a custom redirect_uri

I'm trying to use this library in conjunction with a React application and I'm implementing a LinkedIN login.

The issue I'm facing is that my redirect_uri is different from the default python social auth value. I'm receiving the authorization code on the front-end and triggering the mutation, however I'm receiving a graphql.error.located_error.GraphQLLocatedError: Your credentials aren't allowed error, most probably because of the different redirect_uri values (LinkedIN is enforcing using the same redirect_uri).

Previously, I was using the django-rest-social-auth package that provides for supplying a value for the redirect_uri value. I was wondering if something similar is possible using django-graphql-social-auth.

Social user creation override other user account information

Hi,
The issue i have discovered is that when i create a createsuperuser with incomplete information (firstname , lastname... missing) the social user creation just override the superuser account with his missing information.

Step to follow :

  1. create a superuser with the django command :
    $ manage.py createsuperuser

  2. use the graphQL social auth to create your user :
    mutation token_authentication { socialAuthToken(accessToken: "xxxxBiBQGGLzTUwZD", provider: "facebook") { social { id uid user { username email firstName lastName } provider extraData } token } }

Expected :
A User is created thanks to the social auth module.
So we should have 2 users in the database :

  • root user (created with the createsuperuser command)
  • user1 (created with the socialauthToken mutation)

Real Behavior :
The social user is not created.
The information from the social user override the missing root user information.
Root user information before user social connection :

  • username = root | email = [email protected] | password = xxxx | firstname="" |lastname=""

Root user information after user social connection :

  • username = root | email = [email protected] | password = xxxx | firstname="user1_firstname" |lastname="user1_lastname"

The 2 accounts are merged

To reproduce it, you can find in attachment :

  • My dockerfile to have my django environment ready
  • settings file
  • schema file
  • url file

Thank you for your help

django-graphql-social-auth_bug.zip

SocialAuthMutation crashes when the auth pipeline returns a redirect

Problem

SocialAuthMutation currently assumes that the social auth pipeline will either return a user instance or None.

However, this fails rather ungracefully when a partial pipeline step (PSA docs) returns an HTTP redirect instead of a user instance:

Traceback (most recent call last):
  File "…/site-packages/graphql/execution/executor.py", line 447, in resolve_or_error
    return executor.execute(resolve_fn, source, info, **args)
  File "…/site-packages/graphql/execution/executors/sync.py", line 16, in execute
    return fn(*args, **kwargs)
  File "…/site-packages/graphql_social_auth/decorators.py", line 28, in wrapper
    login(info.context, user)
  File "…/site-packages/django/contrib/auth/__init__.py", line 155, in login
    request.session[SESSION_KEY] = user._meta.pk.value_to_string(user)
graphql.error.located_error.GraphQLLocatedError: 'HttpResponseRedirect' object has no attribute '_meta'

The relevant code is in psa decorator (code link).

Approach

I'm not sure what the best approach is to deal with this, since there's probably not a universally useful way to handle HTTP redirects in this context, but checking for this and raising a better exception is probably the minimum that could happen, and having some supported and documented way for user code to customise and handle this in some application-specific way would probably be ideal.

How to do customization in case of using SocialAuthJWT?

Hi @mongkok

In the readme there is an example how to customize SocialAuth. Could you please show me how can I do the same using SocialAuthJWT, in order to let me use the next query:

mutation CustomSocialAuth($provider: String!, $accessToken: String!) {
  socialAuth(provider: $provider, accessToken: $accessToken) {
    social {
      uid
    }
    token
    somedata
  }
}

I tried:

class CustomSocialAuth(SocialAuthJWT):
    somedata = graphene.String()

    @classmethod
    def resolve(cls, root, info, social, **kwargs):
        return cls(somedata='some_data')

But in this case query returns "token": null.

Thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.