#33846: Google OAuth2.0 SDK(Google Identity Services) doesn't work on Django 4.0
-------------------------------------+-------------------------------------
     Reporter:  Clark                |                    Owner:  nobody
         Type:  Bug                  |                   Status:  closed
    Component:  Template system      |                  Version:  4.0
     Severity:  Normal               |               Resolution:  invalid
     Keywords:  Google, OAuth,       |             Triage Stage:
  login, Google Identity Services,   |  Unreviewed
  template                           |
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Description changed by Clark:

Old description:

> Hello everyone,
> I'm having difficulty using Django 4.0 with Google OAuth2.0 SDK.
> And I wrote down the specific way to reproduce the problem because this
> is a bit tricky issue to explain with words.
> Please leave a comment, if you have any questions.
>
> \\
>
> ''TL;DR
> Django 4.x and Google OAuth2.0 SDK(new way) conflict for some reasons.
> Anyone who is using Google OAuth2.0 SDK with Django 4x?''
>

> \\
> **The problem**
>
> Google OAuth2.0 SDK(Google Identity Services) doesn't work on Django
> 4.0.x and 4.1.x but works on Django <= 3.2.x
>
> \\ \\
> **Test Environments**
>
> Python 3.9.13
> Python 3.10.4
> &
> Django 3.2.14
> Django 4.0.6
> Django 4.0b1
>

> \\ \\
> **How to setup the test env**
>
> {{{
> $ git clone https://github.com/smallbee3/django-oauth-template.git
>
> $ cd django-oauth-template
> $ pip install -r requirements.txt
>
> # Need to fill in "client_id"
> $ vi mysite/frontend/templates/implicitflow_new_1_gis_only.html
> $ vi mysite/frontend/templates/implicitflow_new_2_gapi_async_await.html
> $ vi mysite/frontend/templates/implicitflow_new_3_gapi_callback.html
>
> # Need to fill in "apiKey" & "clientId"
> $ vi
> mysite/frontend/templates/implicitflow_old_1_gapi_client_library.html
> $ vi mysite/frontend/templates/implicitflow_old_2_js_client_library.html
> ...
> }}}
>
> ''implicitflow_new_1_gis_only.html''
> {{{
> <!DOCTYPE html>
> <html>
>   <head>
>     <script src="https://accounts.google.com/gsi/client";
> onload="initClient()" async defer></script>
>   </head>
>   <body>
>     <script>
>       var client;
>       var access_token;
>
>       function initClient() {
>         console.log('Hello initClient!');
>         client = google.accounts.oauth2.initTokenClient({
>           client_id: 'YOUR_CLIENT_ID',
>           ...
>         });
>       }
> }}}
>
> You need to replace "YOUR_CLIENT_ID" with your Google Client ID
>
> ( * To get your Google Client ID from Google, please refer to below links
> https://youtu.be/xH6hAW3EqLk
> https://www.balbooa.com/gridbox-documentation/how-to-get-google-client-
> id-and-client-secret )
>
> ( * To get your Google API Key from Google, please refer to below links
> https://youtu.be/feM25lZkLkA )
>

>
> \\ \\
> **How to reproduce**
>
> {{{
> $ cd django-oauth-template
> $ cd mysite
> $ python manage.py runserver
> }}}
>
> And then, open browser http://localhost:8000/new1
>
> \\ \\
> **TEST Results**
>
> There are many different ways to implement Google OAuth2.0 SDK. So I
> tried every way as below.
>
> Google Identity Services > Implicit flow examples > The new way >
> (https://developers.google.com/identity/oauth2/web/guides/migration-to-
> gis#the_new_way)
> 1) GIS only : http://localhost:8000/new1 - django3.x (O), django4.x (X)
>
> (Django 3.2.14)
> [[Image(https://user-
> images.githubusercontent.com/35122143/178999080-3e04a618-321a-4cc5-97fb-
> fea47e8c18e8.png)]]
>
> (Django 4.0.6)
> [[Image(https://user-
> images.githubusercontent.com/35122143/178999091-9ffa9ee3-ed13-46f2-8996-d976c13dd03c.png)]]
>

> 2) GAPI async/await : http://localhost:8000/new2 - django3.x (O),
> django4.x (X)
> 3) GAPI callback : http://localhost:8000/new3 - django3.x (O), django4.x
> (X)
>
> Google Identity Services > Implicit flow examples > The old way >
> (https://developers.google.com/identity/oauth2/web/guides/migration-to-
> gis#the_old_way)
> 4) GAPI Client Library : http://localhost:8000/old1 - django3.x (O),
> django4.x (O)
> 5) JS Client Library : http://localhost:8000/old2 - django3.x (O),
> django4.x (O)
>
> Google Identity Services > Authorization code flow examples > The new way
> >
> (https://developers.google.com/identity/oauth2/web/guides/migration-to-
> gis#the_new_way_2)
> 6) Server-side Web Apps : http://localhost:8000/new4 - django3.x (O),
> django4.x (X)
>
> \\
> As you can see the results above, Google Identity Services codes are not
> working on django 4.x.
> But, strangely, the old version of Google SDK which doesn't use callback
> is working well on both Django 3.x and 4.x.
>
> Thus, In my humble opinion, the major reason seems that the callback
> function inside of Google SDK which is rendered by Django code isn't
> called.
>

> ''mysite/frontend/templates/implicitflow_new_1_gis_only.html''
>
> {{{
> <!DOCTYPE html>
> <html>
>   <head>
>     <script src="https://accounts.google.com/gsi/client";
> onload="initClient()" async defer></script>
>   </head>
>   <body>
>     <script>
>       ...
>       function initClient() {
>           ...
>           callback: (tokenResponse) => {
>             console.log('Hello callback!');
>             access_token = tokenResponse.access_token;
>             console.log('access_token: ', access_token);
>           },
>         });
>       }
>      ...
> }}}
>
> \\
>
> On a side note, I compared the request and response from Google Auth
> Server between Django 3.x and 4.x. and there was no difference.
> So, I think Google Auth Server has no problem with regard to this issue
> but Google Client library(https://accounts.google.com/gsi/client) served
> by Django does have an issue.
>
> (Response from Google Auth Server on Django 3.2.14)
> {{{
> [[["gf.sisr",6,null,null,null,null,null,["gf.cr",4,null,null,[4,null,null,null,["{\n
> \"access_token\" : \"ya29.A0AVA9y1sCNWa5H1iHI3Ebjjo4OGX551lV1...63\",\n
> \"token_type\" : \"Bearer\",\n  \"expires_in\" : 3598,\n  \"scope\" :
> \"email profile openid https://www.googleapis.com/auth/calendar.readonly
> https://www.googleapis.com/auth/userinfo.profile
> https://www.googleapis.com/auth/contacts.readonly
> https://www.googleapis.com/auth/userinfo.email\",\n  \"authuser\" :
> \"0\",\n  \"hd\" : \"test.com\",\n  \"prompt\" :
> \"none\"\n}","753749545716-dg8sl....apps.googleusercontent.com","auth712297","http://localhost:8000",null,1]],null,null,[]]],["gf.ttu",1],["e",3,null,null,891]]]
> }}}
>
> (Response from Google Auth Server on Django 4.0.6)
> {{{
> [[["gf.sisr",6,null,null,null,null,null,["gf.cr",4,null,null,[4,null,null,null,["{\n
> \"access_token\" : \"ya29
> .A0AVA9y1viWoIqts1eK57kJEEOXKK2NJrW86O99FPmmLRabPVkceigfo5B5xa-
> RDfIuEdymAyJz52I4udUU...Wp1ZHI4a19BY0t3MDVZQ3U0UEhkeUdHVDBLUQ0163\",\n
> \"token_type\" : \"Bearer\",\n  \"expires_in\" : 3599,\n  \"scope\" :
> \"email profile https://www.googleapis.com/auth/calendar.readonly
> https://www.googleapis.com/auth/userinfo.profile
> https://www.googleapis.com/auth/userinfo.email openid
> https://www.googleapis.com/auth/contacts.readonly\",\n  \"authuser\" :
> \"0\",\n  \"hd\" : \"test.com\",\n  \"prompt\" :
> \"none\"\n}","753749545716-dg....apps.googleusercontent.com","auth717087","http://localhost:8000",null,1]],null,null,[]]],["gf.ttu",1],["e",3,null,null,891]]
> }}}
>
> \\
>
> Plus, I tried testing this Google SDK code with "webpack-dev-
> server"([https://github.com/webpack/webpack-dev-
> server](https://github.com/webpack/webpack-dev-server)) without using
> Django rendering, and it works fine.
> That's why I suspect that the updated Django rendering code in v4.0 is
> the cause of the problem.

New description:

 Hello everyone,
 I'm having difficulty using Django 4.0 with Google OAuth2.0 SDK.
 And I wrote down the specific way to reproduce the problem because this is
 a bit tricky issue to explain with words.
 Please leave a comment, if you have any questions.

 \\

 ''TL;DR
 Django 4.x and Google OAuth2.0 SDK(new way) conflict for some reasons.
 Anyone who is using Google OAuth2.0 SDK with Django 4x?''


 \\
 **The problem**

 Google OAuth2.0 SDK(Google Identity Services) doesn't work on Django 4.0.x
 and 4.1.x but works on Django <= 3.2.x
 ( * The old version of Google OAuth2.0 SDK still works, but will be
 completely deprecated after March 31, 2023 )


 \\ \\
 **Test Environments**

 Python 3.9.13
 Python 3.10.4
 &
 Django 3.2.14
 Django 4.0.6
 Django 4.0b1


 \\ \\
 **How to setup the test env**

 {{{
 $ git clone https://github.com/smallbee3/django-oauth-template.git

 $ cd django-oauth-template
 $ pip install -r requirements.txt

 # Need to fill in "client_id"
 $ vi mysite/frontend/templates/implicitflow_new_1_gis_only.html
 $ vi mysite/frontend/templates/implicitflow_new_2_gapi_async_await.html
 $ vi mysite/frontend/templates/implicitflow_new_3_gapi_callback.html

 # Need to fill in "apiKey" & "clientId"
 $ vi mysite/frontend/templates/implicitflow_old_1_gapi_client_library.html
 $ vi mysite/frontend/templates/implicitflow_old_2_js_client_library.html
 ...
 }}}

 ''implicitflow_new_1_gis_only.html''
 {{{
 <!DOCTYPE html>
 <html>
   <head>
     <script src="https://accounts.google.com/gsi/client";
 onload="initClient()" async defer></script>
   </head>
   <body>
     <script>
       var client;
       var access_token;

       function initClient() {
         console.log('Hello initClient!');
         client = google.accounts.oauth2.initTokenClient({
           client_id: 'YOUR_CLIENT_ID',
           ...
         });
       }
 }}}

 You need to replace "YOUR_CLIENT_ID" with your Google Client ID

 ( * To get your Google Client ID from Google, please refer to below links
 https://youtu.be/xH6hAW3EqLk
 https://www.balbooa.com/gridbox-documentation/how-to-get-google-client-id-
 and-client-secret )

 ( * To get your Google API Key from Google, please refer to below links
 https://youtu.be/feM25lZkLkA )



 \\ \\
 **How to reproduce**

 {{{
 $ cd django-oauth-template
 $ cd mysite
 $ python manage.py runserver
 }}}

 And then, open browser http://localhost:8000/new1

 \\ \\
 **TEST Results**

 There are many different ways to implement Google OAuth2.0 SDK. So I tried
 every way as below.

 Google Identity Services > Implicit flow examples > The new way >
 (https://developers.google.com/identity/oauth2/web/guides/migration-to-
 gis#the_new_way)
 1) GIS only : http://localhost:8000/new1 - django3.x (O), django4.x (X)

 (Django 3.2.14)
 [[Image(https://user-
 images.githubusercontent.com/35122143/178999080-3e04a618-321a-4cc5-97fb-
 fea47e8c18e8.png)]]

 (Django 4.0.6)
 [[Image(https://user-
 
images.githubusercontent.com/35122143/178999091-9ffa9ee3-ed13-46f2-8996-d976c13dd03c.png)]]


 2) GAPI async/await : http://localhost:8000/new2 - django3.x (O),
 django4.x (X)
 3) GAPI callback : http://localhost:8000/new3 - django3.x (O), django4.x
 (X)

 Google Identity Services > Implicit flow examples > The old way >
 (https://developers.google.com/identity/oauth2/web/guides/migration-to-
 gis#the_old_way)
 4) GAPI Client Library : http://localhost:8000/old1 - django3.x (O),
 django4.x (O)
 5) JS Client Library : http://localhost:8000/old2 - django3.x (O),
 django4.x (O)

 Google Identity Services > Authorization code flow examples > The new way
 >
 (https://developers.google.com/identity/oauth2/web/guides/migration-to-
 gis#the_new_way_2)
 6) Server-side Web Apps : http://localhost:8000/new4 - django3.x (O),
 django4.x (X)

 \\
 As you can see the results above, Google Identity Services codes are not
 working on django 4.x.
 But, strangely, the old version of Google SDK which doesn't use callback
 is working well on both Django 3.x and 4.x.

 Thus, In my humble opinion, the major reason seems that the callback
 function inside of Google SDK which is rendered by Django code isn't
 called.


 ''mysite/frontend/templates/implicitflow_new_1_gis_only.html''

 {{{
 <!DOCTYPE html>
 <html>
   <head>
     <script src="https://accounts.google.com/gsi/client";
 onload="initClient()" async defer></script>
   </head>
   <body>
     <script>
       ...
       function initClient() {
           ...
           callback: (tokenResponse) => {
             console.log('Hello callback!');
             access_token = tokenResponse.access_token;
             console.log('access_token: ', access_token);
           },
         });
       }
      ...
 }}}

 \\

 On a side note, I compared the request and response from Google Auth
 Server between Django 3.x and 4.x. and there was no difference.
 So, I think Google Auth Server has no problem with regard to this issue
 but Google Client library(https://accounts.google.com/gsi/client) served
 by Django does have an issue.

 (Response from Google Auth Server on Django 3.2.14)
 {{{
 
[[["gf.sisr",6,null,null,null,null,null,["gf.cr",4,null,null,[4,null,null,null,["{\n
 \"access_token\" : \"ya29.A0AVA9y1sCNWa5H1iHI3Ebjjo4OGX551lV1...63\",\n
 \"token_type\" : \"Bearer\",\n  \"expires_in\" : 3598,\n  \"scope\" :
 \"email profile openid https://www.googleapis.com/auth/calendar.readonly
 https://www.googleapis.com/auth/userinfo.profile
 https://www.googleapis.com/auth/contacts.readonly
 https://www.googleapis.com/auth/userinfo.email\",\n  \"authuser\" :
 \"0\",\n  \"hd\" : \"test.com\",\n  \"prompt\" :
 
\"none\"\n}","753749545716-dg8sl....apps.googleusercontent.com","auth712297","http://localhost:8000",null,1]],null,null,[]]],["gf.ttu",1],["e",3,null,null,891]]]
 }}}

 (Response from Google Auth Server on Django 4.0.6)
 {{{
 
[[["gf.sisr",6,null,null,null,null,null,["gf.cr",4,null,null,[4,null,null,null,["{\n
 \"access_token\" : \"ya29
 .A0AVA9y1viWoIqts1eK57kJEEOXKK2NJrW86O99FPmmLRabPVkceigfo5B5xa-
 RDfIuEdymAyJz52I4udUU...Wp1ZHI4a19BY0t3MDVZQ3U0UEhkeUdHVDBLUQ0163\",\n
 \"token_type\" : \"Bearer\",\n  \"expires_in\" : 3599,\n  \"scope\" :
 \"email profile https://www.googleapis.com/auth/calendar.readonly
 https://www.googleapis.com/auth/userinfo.profile
 https://www.googleapis.com/auth/userinfo.email openid
 https://www.googleapis.com/auth/contacts.readonly\",\n  \"authuser\" :
 \"0\",\n  \"hd\" : \"test.com\",\n  \"prompt\" :
 
\"none\"\n}","753749545716-dg....apps.googleusercontent.com","auth717087","http://localhost:8000",null,1]],null,null,[]]],["gf.ttu",1],["e",3,null,null,891]]
 }}}

 \\

 Plus, I tried testing this Google SDK code with "webpack-dev-
 server"([https://github.com/webpack/webpack-dev-
 server](https://github.com/webpack/webpack-dev-server)) without using
 Django rendering, and it works fine.
 That's why I suspect that the updated Django rendering code in v4.0 is the
 cause of the problem.

 \\

 Lastly, also tried changing the template engine from django-template to
 Jinja to see if template engine is the cause of the issue, but still
 problem remains.

--

-- 
Ticket URL: <https://code.djangoproject.com/ticket/33846#comment:3>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/01070182198f4f1b-b67dab81-c117-4f78-94fd-a4bd7499c13b-000000%40eu-central-1.amazonses.com.

Reply via email to