django-allauth
django-allauth copied to clipboard
Implement authorization using Google Identity Service (Google Sign-In for Websites)
Google has been switching to the Google Identity SDK since April of this year. Now Google returns a JWT token as a Credential Response. Now django-allauth + dj-rest-auth requires the transfer of access_token from the old GAPI. How to implement work with JWT?
https://developers.googleblog.com/2021/08/gsi-jsweb-deprecation.html
Google intends to deprecate the old API by March 31, 2023
Hi, any progress or at least a roadmap for this?
This issue prevents usage of "django-allauth" in apps with newly created Google accounts! Namely, not only "The library will be unavailable for download after the March 31, 2023", BUT "By default, newly created Client IDs are now blocked from using the older Platform Library" (from: https://developers.google.com/identity/sign-in/web/sign-in)
Quick update. The handleCredentialResponse
will return an object which contains the access token under the variable credential
.
handleCredentialResponse(opts) {
const access_token = opts.credential;
// send to django-allauth for validation
}
Follow this guide for updating from the old Google sign-in: https://developers.google.com/identity/gsi/web/guides/migration
This issue should be closed as no update is required to maintain compatibility @pennersr
Hey @steverecio ! Would you mind explaining your solution a bit more in detail?
I got to this point where I have the custom callback function, but the API of allauth expects some query params, at least the "code" one.
The code I see using the old google authentication doesn't look like anything present in the new credential, so how did you solve this?
Thanks
any update on this?
Isn't this already handled here https://github.com/pennersr/django-allauth/pull/3053/files ?
Hi all, I managed to make this work with the JavaScript One Tap, so the user can log in without refreshing the page. Just create a new view /accounts/google-one-tap/
,
import json
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
from django.contrib.auth import login as auth_login
from allauth.socialaccount.providers.google.views import GoogleOAuth2Adapter
from allauth.socialaccount.providers.oauth2.client import OAuth2Error
from allauth.socialaccount.helpers import complete_social_login
from allauth.socialaccount.models import SocialApp
from google.oauth2 import id_token
from google.auth.transport import requests
@csrf_exempt
@require_http_methods(["POST"])
def google_one_tap(request):
credential = json.loads(request.body).get('credential')
google_app = SocialApp.objects.get(provider='google')
client_id = google_app.client_id
payload = None
try:
payload = id_token.verify_oauth2_token(credential, requests.Request(), client_id)
except ValueError as e:
return JsonResponse({"success": False, "error": str(e)})
try:
# Add the JWT token to the payload
# as the AllAuth GoogleOAuth2Adapter expects the token to be in the key 'id_token'
payload['id_token'] = credential
adapter = GoogleOAuth2Adapter(request)
app = adapter.get_provider().get_app(request)
login = adapter.complete_login(request, app, credential, response=payload)
complete_social_login(request, login)
# Use Django's login
auth_login(request, login.user)
return JsonResponse({"success": True, "detail": "Login successful"})
except OAuth2Error as e:
return JsonResponse({"success": False, "error": str(e)})
<script src="https://accounts.google.com/gsi/client" async></script>
<script>
function postCredentialToServer(credential) {
fetch('/accounts/google-one-tap/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
credential: credential
})
}).then(response => response.json()).then(data => {
window.dispatchEvent(new CustomEvent('ONE_TAP_LOGIN', {detail: data}));
});
}
window.onload = function () {
google.accounts.id.initialize({
client_id: 'CLIENT_ID',
callback: (response) => postCredentialToServer(response.credential),
});
}
</script>
Would love to hear any criticism about security and/or alternatives. Hope it might be useful for someone else.
Now supported via 9246957e