RealmTeam / django-rest-framework-social-oauth2

python-social-auth and oauth2 support for django-rest-framework

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Adding a Custom Backed to python-social-auth

Chitrank-Dixit opened this issue · comments

I am trying to add a custom backend and here is the code. I had copied it from Google backend.

class BaseMyAuthAuth(object):
    def get_user_id(self, details, response):
        """Use google email as unique id"""
        if self.setting('USE_UNIQUE_USER_ID', False):
            if 'sub' in response:
                return response['sub']
            else:
                return response['id']
        else:
            return details['email']

    def get_user_details(self, response):
        """Return user details from Google API account"""
        if 'username' in response:
            email = response['username']
        else:
            email = ''

        name, given_name, family_name = (
            response.get('name', ''),
            response.get('given_name', ''),
            response.get('family_name', ''),
        )

        fullname, first_name, last_name = self.get_user_names(
            name, given_name, family_name
        )
        return {'username': email.split('@', 1)[0],
                'email': email,
                'fullname': fullname,
                'first_name': first_name,
                'last_name': last_name}


class BaseMyAuthOAuth2API(BaseMyAuthAuth):
    def user_data(self, access_token, *args, **kwargs):
        """Return user data from Google API"""
        url = urljoin(self.API_URL, '/oauth/me')
        return self.get_json(
            url,
            headers={
                'Authorization': 'Bearer %s' % access_token,
            },
        )

    def revoke_token_params(self, token, uid):
        return {'token': token}

    def revoke_token_headers(self, token, uid):
        return {'Content-type': 'application/json'}


class MyAuthOAuth2(BaseMyAuthOAuth2API, BaseOAuth2):
    """Google OAuth2 authentication backend"""
    name = 'myauth'
    REDIRECT_STATE = False
    API_URL = settings.AUTH_URL
    AUTHORIZATION_URL = settings.AUTH_AUTHORIZE_URL
    ACCESS_TOKEN_URL = settings.AUTH_ACCESS_TOKEN_URL
    ACCESS_TOKEN_METHOD = 'POST'
    # The order of the default scope is important
    #DEFAULT_SCOPE = ['openid', 'email', 'profile']
    EXTRA_DATA = [
        ('refresh_token', 'refresh_token', True),
        ('expires_in', 'expires'),
        ('token_type', 'token_type', True)
    ]

It runs well and fetches all the user data needed, but after that it always try to create a new user, on the other hand. If we see Google backend does not create a new user if the user already exists.

My custom backend gives me issue on this file at path

/venv/lib/python3.6/site-packages/django/contrib/auth/__init__.py

        try:
            user = backend.authenticate(request, **credentials)
        except PermissionDenied:
            # This backend says to stop in our tracks - this user should not be allowed in at all.
            break

and google backend goes to different path
/venv/lib/python3.6/site-packages/rest_framework_social_oauth2/oauth2_grants.py

        try:
            user = backend.do_auth(access_token=request.token)
        except requests.HTTPError as e:
            raise errors.InvalidRequestError(
                description="Backend responded with HTTP{0}: {1}.".format(e.response.status_code,
                                                                          e.response.text),
                request=request)

this is the difference I have found out so far.

I can't really help you out on this one, try to check with python social auth how you should develop your backend.
This library handles only the link between third party backends and tokens not user creation.