109

In my application, I implemented Google signout using jsapi.

I used the url https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=xxxxxx to connect to Google and then https://www.googleapis.com/plus/v1/people/xxxxxx to get user data from google profile.

Now I need to signout the user from Google while clicking a button from my application. How can I implement this in JavaScript, or at least it must ask the Google login page every time the user signs in.

I have tried approval_prompt=force, but seems not to be working.

Hakan Fıstık
  • 16,800
  • 14
  • 110
  • 131
Vinesh EG
  • 1,325
  • 2
  • 9
  • 13

12 Answers12

297

Overview of OAuth: Is the User Who He/She Says He/She is?:

I'm not sure if you used OAuth to login to Stack Overflow, like the "Login with Google" option, but when you use this feature, Stack Overflow is simply asking Google if it knows who you are:

"Yo Google, this Vinesh fella claims that vinesh.e@gmail.com is him, is that true?"

If you're logged in already, Google will say YES. If not, Google will say:

"Hang on a sec Stack Overflow, I'll authenticate this fella and if he can enter the right password for his Google account, then it's him".

When you enter your Google password, Google then tells Stack Overflow you are who you say you are, and Stack Overflow logs you in.

When you logout of your app, you're logging out of your app:

Here's where developers new to OAuth sometimes get a little confused... Google and Stack Overflow, Assembla, Vinesh's-very-cool-slick-webapp, are all different entities, and Google knows nothing about your account on Vinesh's cool webapp, and vice versa, aside from what's exposed via the API you're using to access profile information.

When your user logs out, he or she isn't logging out of Google, he/she is logging out of your app, or Stack Overflow, or Assembla, or whatever web application used Google OAuth to authenticate the user.

In fact, I can log out of all of my Google accounts and still be logged into Stack Overflow. Once your app knows who the user is, that person can log out of Google. Google is no longer needed.

With that said, what you're asking to do is log the user out of a service that really doesn't belong to you. Think about it like this: As a user, how annoyed do you think I would be if I logged into 5 different services with my Google account, then the first time I logged out of one of them, I have to login to my Gmail account again because that app developer decided that, when I log out of his application, I should also be logged out of Google? That's going to get old really fast. In short, you really don't want to do this...

Yeh yeh, whatever, I still want to log the user out Of Google, just tell me how do I do this?

With that said, if you still do want to log a user out of Google, and realize that you may very well be disrupting their workflow, you could dynamically build the logout url from one of their Google services logout button, and then invoke that using an img element or a script tag:

<script type="text/javascript" 
    src="https://mail.google.com/mail/u/0/?logout&hl=en" />

OR

<img src="https://mail.google.com/mail/u/0/?logout&hl=en" />

OR

window.location = "https://mail.google.com/mail/u/0/?logout&hl=en";

If you redirect your user to the logout page, or invoke it from an element that isn't cross-domain restricted, the user will be logged out of Google.

Note that this does not necessarily mean the user will be logged out of your application, only Google. :)

Summary:

What's important for you to keep in mind is that, when you logout of your app, you don't need to make the user re-enter a password. That's the whole point! It authenticates against Google so the user doesn't have to enter his or her password over and over and over again in each web application he or she uses. It takes some getting used to, but know that, as long as the user is logged into Google, your app doesn't need to worry about whether or not the user is who he/she says he/she is.

I have the same implementation in a project as you do, using the Google Profile information with OAuth. I tried the very same thing you're looking to try, and it really started making people angry when they had to login to Google over and over again, so we stopped logging them out of Google. :)

jamesmortensen
  • 33,636
  • 11
  • 99
  • 120
  • 12
    Thank You for your valuable time and such a large description. But my client have a different opinion. Suppose the user login to the application using his google login from a public system and logged out from the application. He may think that he had logged out from google also but actually not! Any other user using the system later will get access to the google account. – Vinesh EG Oct 16 '12 at 10:01
  • 15
    Then your users need to log out of Google too. The point is, they're logging into 2 services. Your users need to learn how to use OAuth. :) I'd suggest educating your client and the users. If you have to, go ahead and show them. It shouldn't take long to implement and then undo later when you realize how much it sucks. :) I didn't believe it for myself until I actually did this and saw how much of a PITA it was to have to log back into Google again every time I logged out of LoopToDo. Consider maybe a message "You're logged out of Vinesh's cool app, don't forget to >log out of Google too – jamesmortensen Oct 16 '12 at 15:23
  • can you login to your app while other google account is online? – CaffeineShots Apr 23 '14 at 02:50
  • @kodewrecker - Not sure about other browsers, but in Chrome you can actually log into multiple Google accounts. Also, once logged into *your* app, you can log out of Google and log into your other account. For instance, I stay logged into Stack Overflow in Chrome, even though I am logged into my work Gmail most of the day. Hope this helps. – jamesmortensen Apr 23 '14 at 04:30
  • 2
    I'm developing a hybrid mobile app (Ionic) with Google OAuth and had the same problem because I wanted to login with different Google accounts but I was always automatically logged in. At the moment I'm making a JSONP asynchronous request to https://accounts.google.com/logout in order to logout the user but this is a "dirty" trick and spits errors to the console but couldn't find any other working solution. Let me know if someone knows a better way. I don't have the issue of logging out the user from other services since it's a hybrid mobile app contained in a web view. – nunoarruda Apr 03 '16 at 12:43
  • @jmort253 Thanks for this explaination. I am writing what i understood. Please correct me if im wrong. I login using google api, i get the details and then google thing is over. I now start session in my own website(nothing to do with google) and when i logout from my website i simply delete my variables (again no google thing req). I have done the exact same way but in this case some cookies are getting created when i authenticate using google which I dont want. any idea how to delete those? – sss999 Apr 09 '16 at 20:21
  • @NunoArruda - I don't recommend that approach because it approaches the world as if your app is the only app in existence. When we design things, we need to design them to play nicely with others. Making me login to my Google account over and over again won't make me like your app. It had better be a really good, convenient solution to some massive problem I'm facing to not make me ditch your app. With that said, I'm not really sure I have an answer to your question. Try posting it as a new Stack Overflow question so those with mobile experience can answer. Good luck! :) – jamesmortensen Apr 14 '16 at 07:04
  • @sss999 - Are the cookies causing problems? If so, what kind? Why is that important? It might be best for you to write a new Stack Overflow question and describe your problem in more detail. Both you and Nuno could reference this post in your question to give more context. Hope this helps? – jamesmortensen Apr 14 '16 at 07:06
  • @jmort253 - no they arent creating any problems I just wanted to know whether there was any way to delete them which there isnt i found out. Thanks for the help :) – sss999 Apr 22 '16 at 21:51
  • @jmort253 what if a user logs back in with a social media account (eg. Facebook or Google)? Does Facebook/Google return an access token to the user after a successful login? I know they provide authorization codes upon initial login (when user gives the permissions). – Apoorv Kansal May 29 '16 at 06:23
  • @ApoorvKansal Once the user gives the permission, there is no need for usernames and passwords or "approvals" anymore. If a user wants to revoke the permission, they can do so through the settings, but this is only necessary if the user doesn't plan on ever using the application ever again. Hope this helps. – jamesmortensen May 29 '16 at 19:06
  • 1
    @jmort253 Yeah I understand that they don't need to provide permissions anymore, but how should I authenticate them again? Please see this question I have made (i am still new to OAuth): http://stackoverflow.com/questions/37515836/reauthenticate-user-from-google-facebook-accounts – Apoorv Kansal May 29 '16 at 23:16
  • @jmort253 Isn't log out an important feature to support with OAuth? Imagine if your application is a middleware that allows a user to connect to a google account (service sign in) after the user already has signed into the account (account sign in). Imagine in this use case, The user wants to disconnect from the google service while in the application. If there is not log out, what happens is the store cookie will auto authenticate you back in. – darewreck Jan 10 '17 at 20:21
  • 3
    @jmort253 However, what if to the user the word "disconnect" implies total log out of the application.. Because it auto logs back in without typing in the credentials again, there is 2 issues; user wonders what happen I just disconnected and it should not have my info and second user won't be able to sign into a different account because it will always auto log in unless the auth provider provides a force-login method. So in this case, logout is desirable so that it can invalidate the cookies and you no longer have to worry about how its managed on the client side. – darewreck Jan 10 '17 at 20:21
  • @jmort253 Since google provides a method for us to logout user from the our app `auth2.signOut()`. What does it exactly do in a web app? I know in order to logout user from my web app i need to call my own server script/code. So whats the use of `auth2.signOut()` as shown in google documentation? Any idea? Good explanation btw. – FreeKrishna Feb 10 '17 at 11:22
  • @FreeKrishna - I am not sure. I'd suggest googling it and if you don't come up with another Stack Overflow post or answer on the subject, it could make a good question to post. Good luck! :) – jamesmortensen Feb 10 '17 at 12:20
  • @jmort253 I actually found out that the `auth2.signOut()` does not work on localhost :p . Since we specify an specific url in OAuth Project , when creating an client id, it creates a specific token for that client ID and on calling `auth2.signOut();` only the token get invalidated. So in order to sign in the user will have to authorize once again via google id. Thanks for the quick response :) – FreeKrishna Feb 10 '17 at 14:11
  • @jmort253 I have pretty much the same question, but in the context of python/flask. While I understand that logging out of Google is a messy approach, surely there's a more elegant way that Google provides to do it? I'd highly appreciate it if you could take a look at my question here: https://stackoverflow.com/questions/47150564/how-to-log-user-out-of-an-app-that-uses-google-oauth2-sign-in – kranberry Nov 07 '17 at 05:37
  • 1
    This is useful for Electron applications, where the user logged in with Google! In this case, logging them out of Google logs them out of only one app (the Electron app). – trusktr Apr 17 '19 at 00:42
  • 1
    Been looking for answers for days. This is by far the best in plain English! It explains what's from Google's point of view, relationship of G's authentication service and a specific app using it. The key to **data-sensitive** app end users (including me) is, you the app provides a `log out` button, but I'm **ALWAYS IN** not even need to say I'm who! **Crap!** Since every app has a `clientID` using G's authentication and is part of `idToken`, will solve this dilemma if Google provides an option to **Log out this app only**. Google, app, developers and users all win! Hope Google hears this. – Jeb50 Jun 16 '21 at 18:59
27

You can log out and redirect to your site:

var logout = function() {
    document.location.href = "https://www.google.com/accounts/Logout?continue=https://appengine.google.com/_ah/logout?continue=http://www.example.com";
}
blacktide
  • 10,654
  • 8
  • 33
  • 53
lgabster
  • 695
  • 7
  • 17
7

For me, it works (java - android)

void RevokeAcess()
{
    try{
    HttpClient client = new DefaultHttpClient();
    HttpPost post = new HttpPost("https://accounts.google.com/o/oauth2/revoke?token="+ACCESS_TOKEN);
    org.apache.http.HttpResponse response = client.execute(post);
    }
    catch(IOException e)
    {
    }
    CookieManager.getInstance().removeAllCookie(); // this is clear the cookies which tends to same user in android web view
}

You have to call this function in AsyncTask in android

Vinoj John Hosan
  • 6,448
  • 2
  • 41
  • 37
  • 2
    While it is true that this would work, the question is actually asking about JavaScript, not Java. – jamesmortensen May 13 '14 at 00:32
  • 2
    That sounds freaky that all you need is a token, you can brute force google to forcibly logout everyone. – Archimedes Trajano Nov 03 '14 at 13:44
  • It wont log out you from device, it will log out only the application(in android). – Vinoj John Hosan Nov 03 '14 at 14:20
  • 3
    From looking at some of the [google oauth2 docs](https://developers.google.com/identity/protocols/OAuth2InstalledApp) a typical access token looks like this. "1/fFAGRNJru1FTz70BzhT3Zg" Assuming the "1/" part is just for humans to identify the number easier. You still have two alphabets (upper and lower case) plus ten numerical digits with a length of 22 characters. That's 22^(26*2+10) which equals 1.6990502e+83. Or about the [number of atoms in the known universe](https://en.wikipedia.org/wiki/Observable_universe#Matter_content). Good luck brute forcing that over HTTP. ;) – Chris Balogh Jan 11 '16 at 00:16
  • This does not seem to revoke refresh token, which could be stolen before removing cookies (if it is stored there). – Ondrej Galbavý Apr 04 '16 at 11:47
3

To logout from the app only but not the Gmail:

window.gapi.load('auth2', () => {
      window.gapi.auth2
        .init({
          client_id:
            '<Your client id configired on google console>'
        })
        .then(() => {
          window.gapi.auth2
            .getAuthInstance()
            .signOut()
            .then(function() {
              console.log('User signed out.');
            });
        });
    });

I'm using above in my ReactJs code.

  • 1
    works great! Especially if you're on page where `gapi` is not available anymore, so this actually init and logout. – oavi Jul 31 '21 at 21:19
2

This works to sign the user out of the application, but not Google.

var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
  console.log('User signed out.');
});

Source: https://developers.google.com/identity/sign-in/web/sign-in

CamHart
  • 3,825
  • 7
  • 33
  • 69
  • 1
    this won't completely sign out the user from his/her google account. It only destroys the `AuthInstance` which you used. Your [source](https://developers.google.com/identity/sign-in/web/sign-in) itself says... "_You can enable users to **sign out of your app without signing out of Google**..._" – Roshana Pitigala Dec 16 '17 at 10:53
  • @RoshanaPitigala updated the answer to specify. This answer is the answer to the title of the question, but once you read the question in more details you understand the title was incorrectly written. This answer works for anyone who made it here according to the title of the question. – CamHart Jun 13 '18 at 20:41
2

You can simply Create a logout button and add this link to it and it will utimately log you out from the app and will redirect to your desired site:

https://appengine.google.com/_ah/logout?continue=http://www.YOURSITE.com

just toggle YOURSITE with your website

1

Ouath just makes the Google instance null, hence it you out of Google. Now that's how the architecture is made. Logging out of Google, if you Logout of your app is a dirty work, but can't help if the requirement stipulates the same. Hence add the following to your signOut() function. My project was an Angular 6 app:

document.location.href = "https://www.google.com/accounts/Logout?continue=https://appengine.google.com/_ah/logout?continue=http://localhost:4200";

Here localhost:4200 is the URL of my app. If your login page is xyz.com then input that.

Rahul Sharma
  • 329
  • 1
  • 3
  • 10
1

this code will work to sign out

    <script>
      function signOut() 
      {
        var auth2 = gapi.auth2.getAuthInstance();
        auth2.signOut().then(function () {   
        console.log('User signed out.');   
        auth2.disconnect();   
      }); 
        auth2.disconnect();
      } 
    </script>
Sourabh Kumar Sharma
  • 2,864
  • 3
  • 25
  • 33
0

I hope we can achieve this by storing the token in session while logging in and access the token when he clicked on logout.

    String _accessToken=(String)session.getAttribute("ACCESS_TOKEN");
    if(_accessToken!=null)
    {
        StringBuffer path=httpRequest.getRequestURL();
        reDirectPage="https://www.google.com/accounts/Logout?
        continue=https://appengine.google.com/_ah/logout?
        continue="+path;
    }
    response.sendRedirect(reDirectPage);
Janakiram
  • 1
  • 1
0

It looks like Google recently broke something with their revoke stuff (it's started returning 400 errors for us). You now have to call

auth2.disconnect();

In our case we then have to wait a couple of seconds for the disconnect call to complete otherwise the sign-in code will re-authorise before it's done. It'd be good if google returned a promise from the disconnect method.

Sean
  • 2,033
  • 2
  • 23
  • 28
0

If any one want it in Java, Here is my Answer, For this you have to call Another Thread.

Noor Hossain
  • 1,620
  • 1
  • 18
  • 25
0
1. Try this code, if you are using onSignIn() function
2.
        <script src="https://apis.google.com/js/platform.js?onload=onLoad" async defer></script>
       <script>
       function signOut() {
       onLoad();
       var auth2 = gapi.auth2.getAuthInstance();
       auth2.signOut().then(function () {
       console.log('User signed out.');
       if(auth2.isSignedIn)
       {
          auth2.isSignedIn.set(false);
       }
       });
       }
       function onLoad() {
          gapi.load('auth2', function() {
            gapi.auth2.init();
          });
        }
        </script>