I have implemented django rest auth with Allauth and its working fine if I login through google access_token
but there is a case when some client device need to login by google id_token
.
I am getting error if I use id_token
instead of access_token
{
"non_field_errors": [
"Incorrect value"
]
}
please help me out
django-allauth is an integrated set of Django applications dealing with account authentication, registration, management, and third-party (social) account authentication. It is one of the most popular authentication modules due to its ability to handle both local and social logins.
Django Setup Set up the initial tables and add a superuser: $ python manage.py migrate Operations to perform: Apply all migrations: admin, contenttypes, auth, sessions Running migrations: Applying contenttypes. 0001_initial... OK Applying auth. 0001_initial... OK Applying admin.
Dj-Rest-Auth: a free and open-source package used for handling authentication in Django REST APIs.
Update your files like
../allauth/socialaccount/providers/google/provider.py
:
class GoogleProvider(OAuth2Provider):
....
def extract_uid(self, data):
try:
return str(data['id'])
except KeyError:
return str(data['user_id'])
../allauth/socialaccount/providers/google/views.py
:
class GoogleOAuth2Adapter(OAuth2Adapter):
provider_id = GoogleProvider.id
access_token_url = 'https://accounts.google.com/o/oauth2/token'
authorize_url = 'https://accounts.google.com/o/oauth2/auth'
profile_url = 'https://www.googleapis.com/oauth2/v1/userinfo'
token_url = 'https://www.googleapis.com/oauth2/v1/tokeninfo'
def complete_login(self, request, app, token, **kwargs):
if 'rest-auth/google' in request.path:
print('rest-auth api')
# /api/rest-auth/google
# but not for website login with google
resp = requests.get(self.token_url,
params={'id_token': token.token,
'alt': 'json'})
else:
print('else else rest-auth api')
resp = requests.get(self.profile_url,
params={'access_token': token.token,
'alt': 'json'})
resp.raise_for_status()
extra_data = resp.json()
login = self.get_provider() \
.sociallogin_from_response(request,
extra_data)
return login
oauth2_login = OAuth2LoginView.adapter_view(GoogleOAuth2Adapter)
oauth2_callback = OAuth2CallbackView.adapter_view(GoogleOAuth2Adapter)
For using id_token you will get only these fileds (access_type, audience, email, email_verified, expires_in, issued_at, issued_to, issuer, nonce, scope, user_id, verified_email). So if your user table required phone and name you can set the to empty name=''
etc. For this you can use the following code.
Set user model required fields to empty for covering id_token case
It depends upon your user model, in my case we need both phone and name so I have set them empty. If you don't do this you will get failed constraints errors.
../allauth/socialaccount/providers/base.py
class Provider(object):
def sociallogin_from_response(self, request, response):
....
common_fields = self.extract_common_fields(response)
common_fields['name'] = common_fields.get('name', '')
common_fields['phone'] = common_fields.get('phone', '')
common_fields['username'] = uid
....
I have set the username to user id obtained from social platform api. Later I am forcing user to update its details (username, name, phone etc).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With