Click here to Skip to main content
15,881,281 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi

What I am doing :

I am trying to use google sign in button so that I can get a tokenId and send it to the django rest api where it can verify with Google api and create a new user from the email retrieved (if the user is not registered by the email ID) and respond with a default Token (Django Rest Frameworks's) to the Android Client so that it can further be used to do some CRUD operations for the DRF

How I am doing :

1. I created two credentials, one for the Android App and the other for the web app


2. Added the SHA-1 fingerprint in the Android credential by copying it from Android studio's gradle signingReport (Without providing SHA-1 to the credential one will not get the desired idToken )

What I have tried:

3. Then I am manually getting the tokenId


Java
private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
    try {
        GoogleSignInAccount account = completedTask.getResult(ApiException.class);

        // Signed in successfully, show authenticated UI.
        updateUI(account);
    } catch (ApiException e) {
        // The ApiException status code indicates the detailed failure reason.
        // Please refer to the GoogleSignInStatusCodes class reference for more information.
        Log.w(this.getLocalClassName(), "signInResult:failed code=" + e.getStatusCode());
        updateUI(null);
    }
}




private void  updateUI(GoogleSignInAccount account){
    Toast.makeText(this,"SUCCESS",Toast.LENGTH_SHORT).show();
    Log.w(this.getLocalClassName(), "updateUI:::SUCCESS" + " \nID TOKEN : "+account.getIdToken()+" \nEMAIL : "+account.getEmail()+" \nNAME : "+account.getDisplayName());


} 



4. Then I had followed this toptal link below to create an API in Django where I can post my idToken, verify it with google and if the user exists then respond with an authenticated DRF Token (if the user doesn't exists then create a new one and respond with an auth DRF Token )

Integrate OAuth 2 Into Your Django/DRF Back-end | Toptal[^]


5. My Django code is as followed :

urls.py
Python
re_path(r'^authenticate/(?P<backend>[^/]+)/$',views.exchange_token,name='url_authenticate'),



settings.py

Python
print(SECRET_KEY)

DEBUG = env('DEBUG')

ALLOWED_HOSTS = []



INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',

'api',

'rest_framework',
'rest_framework.authtoken', 
'social_django',    

]

MIDDLEWARE = [
'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',
'social_django.middleware.SocialAuthExceptionMiddleware',   
]

ROOT_URLCONF = 'bitconnect_proj.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',

            'social_django.context_processors.backends',
            'social_django.context_processors.login_redirect',                
        ],
    },
},
]

TEMPLATE_CONTEXT_PROCESSORS = (

'social_django.context_processors.backends',
'social_django.context_processors.login_redirect',
)

REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
    'rest_framework.permissions.IsAuthenticated',
),

'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework.authentication.TokenAuthentication',
),
}   


AUTHENTICATION_BACKENDS = (

'social_core.backends.google.GoogleOAuth2',
'django.contrib.auth.backends.ModelBackend',



)

SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = env('SOCIAL_AUTH_GOOGLE_OAUTH2_KEY')
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = env('SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET')








SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE = [
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile',
]

SOCIAL_AUTH_ADMIN_USER_SEARCH_FIELDS = ['username', 'first_name', 'email']

SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL = True





SOCIAL_AUTH_PIPELINE = (    


'social_core.pipeline.social_auth.social_details',
'social_core.pipeline.social_auth.social_uid',
'social_core.pipeline.social_auth.auth_allowed',
'social_core.pipeline.social_auth.social_user',
'social_core.pipeline.user.get_username',
'social_core.pipeline.social_auth.associate_by_email',
'social_core.pipeline.user.create_user',
'social_core.pipeline.social_auth.associate_user',
'social_core.pipeline.social_auth.load_extra_data',
'social_core.pipeline.user.user_details',

)



WSGI_APPLICATION = 'bitconnect_proj.wsgi.application'



DATABASES = {
'default': {
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': BASE_DIR / 'db.sqlite3',
}
}



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',
},
]

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True



STATIC_URL = '/static/'





views.py

Python
from django.shortcuts import render
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny
from rest_framework.authtoken.models import Token
from rest_framework.response import Response
from social_django.utils import psa
from rest_framework import serializers,status




# Create your views here.

class AuthSerializer(serializers.Serializer):

access_token = serializers.CharField(allow_blank=False,trim_whitespace=True,)


@api_view(http_method_names=['POST'])
@permission_classes([AllowAny])
@psa()
def exchange_token(request,backend):

backend = request.strategy

print("BACKEND:::",backend)


serializer = AuthSerializer(data=request.data)





if serializer.is_valid(raise_exception=True):
    print("HERE........0")
    # This is the key line of code: with the @psa() decorator above,
    # it engages the PSA machinery to perform whatever social authentication
    # steps are configured in your SOCIAL_AUTH_PIPELINE. At the end, it either
    # hands you a populated User model of whatever type you've configured in
    # your project, or None.
    user = request.backend.do_auth(serializer.validated_data['access_token'])


    print("HERE......")

    if user:
        # if using some other token backend than DRF's built-in TokenAuthentication,
        # you'll need to customize this to get an appropriate token object
        token, _ = Token.objects.get_or_create(user=user)
        return Response({'token': token.key})

    else:
        print("HERE .............NO USER EXISTS")
        return Response(
            {'errors': {'token': 'Invalid token'}},
            status=status.HTTP_400_BAD_REQUEST,
        )




6. When I am making a post request on the above endpoint , I am getting this error :





"/home/thebitshoes/Desktop/Environments/voiceconnect_new/lib/python3.8/site-packages/social_core/utils.py",
line 256, in wrapper
raise AuthForbidden(args[0])

Exception Type: AuthForbidden at /authenticate/google-oauth2/
Exception Value: Your credentials aren't allowed





I want to post idToken from Android (after getting it from the SIGN IN operation) to my Django server and get a Token which is a DRF token so that I can make use of the APIs as a authorized user of the DJango app



Thanks in Advance !!
Posted
Comments
Sandeep Mewara 15-Oct-20 3:53am    
Have a look at this: https://www.gitmemory.com/issue/python-social-auth/social-app-django/202/499176896
Member 12731696 15-Oct-20 5:38am    
Hi Sandeep ,

I am making a post request to my django server where it only accepts the access_token

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900