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
private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
try {
GoogleSignInAccount account = completedTask.getResult(ApiException.class);
updateUI(account);
} catch (ApiException e) {
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
re_path(r'^authenticate/(?P<backend>[^/]+)/$',views.exchange_token,name='url_authenticate'),
settings.py
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
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
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")
user = request.backend.do_auth(serializer.validated_data['access_token'])
print("HERE......")
if user:
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 !!