[Python-modules-commits] [python-social-auth] 56/61: Fix Google+ auth complete, update examples with updated SDK usage. Refs #316
Wolfgang Borgert
debacle at moszumanska.debian.org
Sat Dec 24 15:14:07 UTC 2016
This is an automated email from the git hooks/post-receive script.
debacle pushed a commit to tag v0.2.13
in repository python-social-auth.
commit a4918af20e09642b8ee47724a023899ef93fd22b
Author: Matías Aguirre <matiasaguirre at gmail.com>
Date: Mon Aug 31 12:28:21 2015 -0300
Fix Google+ auth complete, update examples with updated SDK usage. Refs #316
---
docs/backends/google.rst | 118 +++++++++++++--------
.../django_example/example/templates/home.html | 90 ++++++++++------
social/backends/google.py | 38 +++----
3 files changed, 151 insertions(+), 95 deletions(-)
diff --git a/docs/backends/google.rst b/docs/backends/google.rst
index affe7f7..64dd66e 100644
--- a/docs/backends/google.rst
+++ b/docs/backends/google.rst
@@ -63,8 +63,9 @@ Google+ Sign-In
done by their Javascript which thens calls a defined handler to complete the
auth process.
-* To enable the backend create an application using the `Google console`_ and
- following the steps from the `official guide`_. Make sure to enable the Google+ API in the console.
+* To enable the backend create an application using the `Google
+ console`_ and following the steps from the `official guide`_. Make
+ sure to enable the Google+ API in the console.
* Fill in the key settings looking inside the Google console the subsection
``Credentials`` inside ``API & auth``::
@@ -81,57 +82,83 @@ auth process.
``SOCIAL_AUTH_GOOGLE_PLUS_SECRET`` corresponds to the variable
``CLIENT SECRET``.
-* Create a new Django view and in its template add the Google+ Sign-In button::
-
- <div id="signinButton">
- <span id="signinButton">
- <span
- class="g-signin"
- data-callback="signInCallback"
- data-clientid="{{ plus_id }}"
- data-cookiepolicy="single_host_origin"
- data-requestvisibleactions="http://schemas.google.com/AddActivity"
- data-scope="https://www.googleapis.com/auth/plus.login">
- </span>
- </span>
- </div>
-
- <form id="google-plus" method="post" action="{% url 'social:complete' "google-plus" %}">
- {% csrf_token %}
- <input id="at" type="hidden" name="access_token" value="" />
- <input id="code" type="hidden" name="code" value="" />
- </form>
-
- ``plus_id`` is the value from ``SOCIAL_AUTH_GOOGLE_PLUS_KEY``.
- ``signInCallback`` is the name of your Javascript callback function.
- If you would like to get user's email address and have it stored, then set
- this value in `data-scope`::
-
- data-scope="https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email"
+* Add the sign-in button to your template, you can use the SDK button
+ or add your own and attacht he click handler to it (check `Google+ Identity Sign-In`_
+ documentation about it)::
+
+ <div id="google-plus-button">Google+ Sign In</div>
* Add the Javascript snippet in the same template as above::
- <script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
+ <script src="https://apis.google.com/js/api:client.js"></script>
+
<script type="text/javascript">
- (function() {
- var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
- po.src = 'https://apis.google.com/js/client:plusone.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
- })();
+ gapi.load('auth2', function () {
+ var auth2;
+
+ auth2 = gapi.auth2.init({
+ client_id: "<PUT SOCIAL_AUTH_GOOGLE_PLUS_KEY HERE>",
+ scope: "<PUT BACKEND SCOPE HERE>"
+ });
+
+ auth2.then(function () {
+ var button = document.getElementById("google-plus-button");
+ console.log("User is signed-in in Google+ platform?", auth2.isSignedIn.get() ? "Yes" : "No");
+
+ auth2.attachClickHandler(button, {}, function (googleUser) {
+ // Send access-token to backend to finish the authenticate
+ // with your application
+
+ var authResponse = googleUser.getAuthResponse();
+ var $form;
+ var $input;
+
+ $form = $("<form>");
+ $form.attr("action", "/complete/google-plus");
+ $form.attr("method", "post");
+ $input = $("<input>");
+ $input.attr("name", "access_token");
+ $input.attr("value", authResponse.access_token);
+ $form.append($input);
+ // Add csrf-token if needed
+ $(document.body).append($form);
+ $form.submit();
+ });
+ });
+ });
</script>
+ {% endif %}
+
+* Logging out
-* And define your Javascript callback function::
+ Logging-out can be tricky when using the the platform SDK because it
+ can trigger an automatic sign-in when listening to the user status
+ change. With the method show above, that won't happen, but if the UI
+ depends more in the SDK values than the backend, then things can get
+ out of sync easilly. To prevent this, the user should be logged-out
+ from Google+ platform too. This can be accomplished by doing::
<script type="text/javascript">
- var signInCallback = function (result) {
- if (result['error']) {
- alert('An error happened:', result['error']);
- } else {
- $('#code').attr('value', result['code']);
- $('#at').attr('value', result['access_token']);
- $('#google-plus').submit();
- }
- };
+ gapi.load('auth2', function () {
+ var auth2;
+
+ auth2 = gapi.auth2.init({
+ client_id: "{{ plus_id }}",
+ scope: "{{ plus_scope }}"
+ });
+
+ auth2.then(function () {
+ if (auth2.isSignedIn.get()) {
+ $('#logout').on('click', function (event) {
+ event.preventDefault();
+ auth2.signOut().then(function () {
+ console.log("Logged out from Google+ platform");
+ document.location = "/logout";
+ });
+ });
+ }
+ });
+ });
</script>
@@ -223,3 +250,4 @@ supporting them you can default to the old values by defining this setting::
.. _official guide: https://developers.google.com/+/web/signin/#step_1_create_a_client_id_and_client_secret
.. _Sept 1, 2014: https://developers.google.com/+/api/auth-migration#timetable
.. _e3525187: https://github.com/omab/python-social-auth/commit/e35251878a88954cecf8e575eca27c63164b9f67
+.. _Google+ Identity Sign-In: https://developers.google.com/identity/sign-in/web/sign-in
diff --git a/examples/django_example/example/templates/home.html b/examples/django_example/example/templates/home.html
index 3a51c59..58b7ec8 100644
--- a/examples/django_example/example/templates/home.html
+++ b/examples/django_example/example/templates/home.html
@@ -11,7 +11,7 @@
.col-md-2 { width: 18.6667%; }
.buttons { display: block; table-layout: fixed; border-radius: 7px; border: 1px solid #ccc;
margin: 20px; background: #eee; padding: 30px; }
- .buttons > div a { margin: 5px 10px; }
+ .buttons > div .btn { margin: 5px 10px; }
.buttons > div:not(:first-child) { margin-top: 10px; border-top: 1px solid #ccc;
padding-top: 10px; text-align: center; }
.user-details { text-align: center; font-size: 16px; font-weight: bold; }
@@ -35,17 +35,24 @@
{% for name, backend in sublist %}
{% associated backend %}
{% if association %}
- <form class="disconnect-form col-md-2" action="{% url "social:disconnect_individual" backend=association.provider association_id=association.id %}" method="post">{% csrf_token %}
+ <form class="disconnect-form col-md-2" id="{{ name }}-disconnect" action="{% url "social:disconnect_individual" backend=association.provider association_id=association.id %}" method="post">{% csrf_token %}
<a class="btn btn-danger" name="{{ backend|backend_class }}" href="#">
<i class="fa fa-{{ name|icon_name }}"></i>
Disconnect {{ backend|backend_name }}
</a>
</form>
{% else %}
- <a class="col-md-2 btn btn-default" name="{{ backend|backend_class }}" href="{% url "social:begin" backend=name %}">
- <i class="fa fa-{{ name|icon_name }}"></i>
- {{ backend|backend_name }}
- </a>
+ {% if name == "google-plus" %}
+ <div class="col-md-2 btn btn-default" id="{{ name }}-button" name="{{ backend|backend_class }}">
+ <i class="fa fa-{{ name|icon_name }}"></i>
+ {{ backend|backend_name }}
+ </div>
+ {% else %}
+ <a class="col-md-2 btn btn-default" id="{{ name }}-button" name="{{ backend|backend_class }}" href="{% url "social:begin" backend=name %}">
+ <i class="fa fa-{{ name|icon_name }}"></i>
+ {{ backend|backend_name }}
+ </a>
+ {% endif %}
{% endif %}
{% endfor %}
</div>
@@ -77,7 +84,7 @@
</div>
<div>
- <a class="btn btn-primary" href="/logout/">
+ <a class="btn btn-primary" href="/logout/" id="logout">
<i class="fa fa-sign-out"></i>
Logout
</a>
@@ -322,38 +329,57 @@
</div>
{% if plus_id %}
- <form id="google-plus" method="post" action="{% url "social:complete" backend="google-plus" %}">{% csrf_token %}
- <input id="at" type="hidden" name="access_token" value="" />
- <input id="code" type="hidden" name="code" value="" />
-
- <div id="signinButton">
- <span class="g-signin" data-scope="{{ plus_scope }}"
- data-clientid="{{ plus_id }}"
- data-redirecturi="postmessage"
- data-accesstype="offline"
- data-cookiepolicy="single_host_origin"
- data-callback="signInCallback">
- </span>
- </div>
- </form>
+ <script src="https://apis.google.com/js/api:client.js"></script>
+ <script type="text/javascript">
+ gapi.load('auth2', function () {
+ var auth2;
+
+ auth2 = gapi.auth2.init({
+ client_id: "{{ plus_id }}",
+ scope: "{{ plus_scope }}"
+ });
+
+ auth2.then(function () {
+ var button = document.getElementById("google-plus-button");
+ console.log("User is signed-in in Google+ platform?", auth2.isSignedIn.get() ? "Yes" : "No");
+
+ if (button) {
+ auth2.attachClickHandler(button, {}, function (googleUser) {
+ var authResponse = googleUser.getAuthResponse();
+ var $form;
+ var $input;
+
+ $form = $("<form>");
+ $form.attr("action", "{% url "social:complete" backend="google-plus" %}");
+ $form.attr("method", "post");
+ $input = $("<input>");
+ $input.attr("name", "access_token");
+ $input.attr("value", authResponse.access_token);
+ $form.append($input);
+ $form.append("{% csrf_token %}");
+ $(document.body).append($form);
+ $form.submit();
+ });
+ } else if (auth2.isSignedIn.get()) {
+ $('#logout').on('click', function (event) {
+ event.preventDefault();
+
+ auth2.signOut().then(function () {
+ console.log("Logged out from Google+ platform");
+ document.location = $(event.target).attr('href');
+ });
+ });
+ }
+ });
+ });
+ </script>
{% endif %}
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
- <script src="https://plus.google.com/js/client:plusone.js?onload=start" type="text/javascript"></script>
<script src="https://login.persona.org/include.js" type="text/javascript"></script>
<script type="text/javascript">
- var signInCallback = function (result) {
- if (result['error']) {
- alert('An error happened:', result['error']);
- } else {
- $('#code').attr('value', result['code']);
- $('#at').attr('value', result['access_token']);
- $('#google-plus').submit();
- }
- };
-
var modalDialog = function (modalId, modalLinkName, submitHandler) {
var $modal;
diff --git a/social/backends/google.py b/social/backends/google.py
index bc37d2d..8affe6d 100644
--- a/social/backends/google.py
+++ b/social/backends/google.py
@@ -113,6 +113,7 @@ class GooglePlusAuth(BaseGoogleOAuth2API, BaseOAuth2):
REVOKE_TOKEN_METHOD = 'GET'
DEFAULT_SCOPE = [
'https://www.googleapis.com/auth/plus.login',
+ 'https://www.googleapis.com/auth/plus.me',
]
DEPRECATED_DEFAULT_SCOPE = [
'https://www.googleapis.com/auth/plus.login',
@@ -136,26 +137,27 @@ class GooglePlusAuth(BaseGoogleOAuth2API, BaseOAuth2):
@handle_http_errors
def auth_complete(self, *args, **kwargs):
- if 'access_token' in self.data and 'code' not in self.data:
- raise AuthMissingParameter(self, 'access_token or code')
-
- # Token won't be available in plain server-side workflow
- token = self.data.get('access_token')
- if token:
- self.process_error(self.get_json(
+ if 'access_token' in self.data: # Client-side workflow
+ token = self.data.get('access_token')
+ response = self.get_json(
'https://www.googleapis.com/oauth2/v1/tokeninfo',
params={'access_token': token}
- ))
-
- response = self.request_access_token(
- self.ACCESS_TOKEN_URL,
- data=self.auth_complete_params(),
- headers=self.auth_headers(),
- method=self.ACCESS_TOKEN_METHOD
- )
- self.process_error(response)
- return self.do_auth(response['access_token'], response=response,
- *args, **kwargs)
+ )
+ self.process_error(response)
+ return self.do_auth(token, response=response, *args, **kwargs)
+ elif 'code' in self.data: # Server-side workflow
+ response = self.request_access_token(
+ self.ACCESS_TOKEN_URL,
+ data=self.auth_complete_params(),
+ headers=self.auth_headers(),
+ method=self.ACCESS_TOKEN_METHOD
+ )
+ self.process_error(response)
+ return self.do_auth(response['access_token'],
+ response=response,
+ *args, **kwargs)
+ else:
+ raise AuthMissingParameter(self, 'access_token or code')
class GoogleOAuth(BaseGoogleAuth, BaseOAuth1):
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-social-auth.git
More information about the Python-modules-commits
mailing list