Jak wylogować się z aplikacji, w której używałem OAuth2 do logowania się z Google?

84

W mojej aplikacji zaimplementowałem wylogowanie Google za pomocą jsapi.

Użyłem adresu URL https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=xxxxxx, aby połączyć się z Google, a następnie https://www.googleapis.com/plus/v1/people/xxxxxx, aby uzyskać dane użytkownika z profilu Google.

Teraz muszę wylogować użytkownika z Google, klikając przycisk w mojej aplikacji. Jak mogę to zaimplementować w JavaScript, a przynajmniej musi pytać stronę logowania Google za każdym razem, gdy użytkownik się loguje.

Próbowałem approval_prompt=force, ale wygląda na to, że nie działa.

Vinesh EG
źródło

Odpowiedzi:

244

Omówienie protokołu OAuth: czy użytkownik jest tym, za kogo się podaje ?:

Nie jestem pewien, czy użyłeś OAuth do zalogowania się do Stack Overflow, na przykład opcji „Zaloguj się przez Google”, ale kiedy używasz tej funkcji, Stack Overflow po prostu pyta Google, czy wie, kim jesteś:

„Yo Google, ten gość z Vinesh twierdzi, że to on [email protected], czy to prawda?”

Jeśli jesteś już zalogowany, Google powie TAK. Jeśli nie, Google powie:

„Poczekaj sekundę Przepełnienie stosu, uwierzytelnię tego gościa i jeśli będzie mógł wprowadzić prawidłowe hasło do swojego konta Google, to będzie to on”.

Gdy wpiszesz swoje hasło Google, Google powie Stack Overflow, za kogo się podajesz, a Stack Overflow Cię zaloguje.

Po wylogowaniu z aplikacji, jesteś zalogowaniu z Twojej aplikacji:

Oto, gdzie programiści nowi w OAuth czasami są trochę zdezorientowani ... Google i Stack Overflow, Assembla, bardzo fajna-zgrabna-aplikacja internetowa Vinesha, to różne podmioty, a Google nic nie wie o Twoim koncie w fajnej aplikacji internetowej Vinesha i wice odwrotnie, poza tym, co jest ujawniane za pośrednictwem interfejsu API, którego używasz do uzyskiwania dostępu do informacji o profilu.

Kiedy użytkownik się wylogowuje, nie wylogowuje się z Google, wylogowuje się z Twojej aplikacji, Stack Overflow, Assembla lub jakiejkolwiek innej aplikacji internetowej używającej Google OAuth do uwierzytelnienia użytkownika.

W rzeczywistości mogę wylogować się ze wszystkich moich kont Google i nadal być zalogowanym do Stack Overflow. Gdy Twoja aplikacja będzie wiedzieć, kim jest użytkownik, ta osoba będzie mogła wylogować się z Google. Google nie jest już potrzebne.

Mając to na uwadze, prosisz o wylogowanie użytkownika z usługi, która tak naprawdę nie należy do Ciebie. Pomyśl o tym w ten sposób: jako użytkownik, jak myślisz, jak bardzo byłbym zirytowany, gdybym zalogował się do 5 różnych usług za pomocą mojego konta Google, a potem gdy pierwszy raz wylogowałem się z jednej z nich, muszę zalogować się na swoje konto Gmail znowu dlatego, że ten programista aplikacji zdecydował, że kiedy wyloguję się z jego aplikacji, powinienem również zostać wylogowany z Google? To szybko się zestarzeje. Krótko mówiąc, naprawdę nie chcesz tego robić ...

Tak, tak, nieważne, nadal chcę wylogować użytkownika z Google, po prostu powiedz mi, jak mam to zrobić?

Mając to na uwadze, jeśli nadal chcesz wylogować użytkownika z Google i zdasz sobie sprawę, że możesz bardzo dobrze zakłócać jego przepływ pracy, możesz dynamicznie utworzyć adres URL wylogowania z jednego z ich przycisku wylogowania z usług Google, a następnie wywołać go za pomocą element img lub tag skryptu:

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

LUB

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

LUB

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

Jeśli przekierujesz użytkownika na stronę wylogowania lub wywołasz go z elementu, który nie jest ograniczony między domenami, użytkownik zostanie wylogowany z Google.

Pamiętaj, że nie musi to oznaczać, że użytkownik zostanie wylogowany z Twojej aplikacji, tylko Google. :)

Podsumowanie:

Ważne jest, aby pamiętać, że po wylogowaniu się z aplikacji nie trzeba zmuszać użytkownika do ponownego wprowadzania hasła. O to chodzi! Uwierzytelnia się w Google, więc użytkownik nie musi w kółko wpisywać swojego hasła w każdej używanej przez siebie aplikacji internetowej. Przyzwyczajenie się do tego wymaga trochę czasu, ale pamiętaj, że dopóki użytkownik jest zalogowany w Google, Twoja aplikacja nie musi się martwić o to, czy użytkownik jest tym, za kogo się podaje.

Mam taką samą implementację w projekcie jak Ty, używając informacji z profilu Google z OAuth. Wypróbowałem to samo, co chcesz spróbować, i naprawdę zaczęło denerwować ludzi, gdy musieli ciągle logować się do Google, więc przestaliśmy wylogowywać ich z Google. :)

jmort253
źródło
8
Dziękuję za cenny czas i tak obszerny opis. Ale mój klient ma inne zdanie. Załóżmy, że użytkownik loguje się do aplikacji przy użyciu swojego loginu google z systemu publicznego i wylogowuje się z aplikacji. Może pomyśleć, że wylogował się z Google, ale w rzeczywistości nie! Każdy inny użytkownik korzystający z systemu później uzyska dostęp do konta Google.
Vinesh EG
13
Następnie Twoi użytkownicy również muszą wylogować się z Google. Chodzi o to, że logują się do 2 usług. Twoi użytkownicy muszą się nauczyć, jak korzystać z OAuth. :) Sugerowałbym edukację klienta i użytkowników. Jeśli musisz, idź i pokaż im. Wdrożenie nie powinno zająć dużo czasu, a później cofnąć się, gdy zdasz sobie sprawę, jak bardzo jest do bani. :) Sam nie wierzyłem w to, dopóki nie zrobiłem tego i nie zobaczyłem, ile PITA to konieczność ponownego logowania się do Google za każdym razem, gdy wylogowałem się z LoopToDo. Rozważ na przykład komunikat „Wylogowałeś się z fajnej aplikacji Vinesha, nie zapomnij też> wylogować się z Google <!”
jmort253
1
@ jmort253 Tak, rozumiem, że nie muszą już podawać uprawnień, ale jak mam je ponownie uwierzytelnić? Zobacz to pytanie, które zadałem (nadal jestem nowy w OAuth): stackoverflow.com/questions/37515836/…
Apoorv Kansal
1
@ jmort253 A co, jeśli dla użytkownika słowo „rozłącz” oznacza całkowite wylogowanie z aplikacji. Ponieważ loguje się ona automatycznie bez ponownego wpisywania poświadczeń, występują 2 problemy; użytkownik zastanawia się, co się stało. Właśnie się rozłączyłem i nie powinno mieć moich informacji, a drugi użytkownik nie będzie mógł zalogować się na inne konto, ponieważ zawsze będzie logował się automatycznie, chyba że dostawca uwierzytelniania zapewni metodę wymuszonego logowania. W tym przypadku wylogowanie jest pożądane, aby mogło unieważnić pliki cookie i nie musisz już martwić się o to, jak jest zarządzany po stronie klienta.
darewreck
1
Jest to przydatne w aplikacjach Electron, w których użytkownik jest zalogowany w Google! W takim przypadku wylogowanie ich z Google powoduje wylogowanie ich tylko z jednej aplikacji (aplikacji Electron).
trusktr
21

Możesz się wylogować i przekierować do swojej witryny:

var logout = function() {
    document.location.href = "https://www.google.com/accounts/Logout?continue=https://appengine.google.com/_ah/logout?continue=http://www.example.com";
}
lgabster
źródło
1
Wreszcie! Dziękuję Ci! Cały dzień starałem się znaleźć sposób na wylogowanie się, aby uniemożliwić następnemu użytkownikowi zalogowanie się jako poprzedni użytkownik jednym kliknięciem, bez znajomości adresu e-mail ani hasła ...
około
1
Nie działa, bo wystarczy otworzyć tę samą stronę w innej zakładce i jesteś zalogowany ponownie ...
Bartłomiej Semańczyk
5

U mnie działa (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
}

Musisz wywołać tę funkcję w AsyncTask w systemie Android

Vinoj John Hosan
źródło
2
Chociaż prawdą jest, że to zadziała, pytanie w rzeczywistości dotyczy JavaScript, a nie Javy.
jmort253
2
To brzmi dziwnie, że wszystko, czego potrzebujesz, to token, możesz brutalnie zmusić Google do wymuszonego wylogowania wszystkich.
Archimedes Trajano
Nie wyloguje Cię z urządzenia, wyloguje tylko aplikację (w systemie Android).
Vinoj John Hosan
2
Patrząc na niektóre dokumenty Google oauth2, typowy token dostępu wygląda następująco. „1 / fFAGRNJru1FTz70BzhT3Zg” Zakładając, że część „1 /” jest przeznaczona tylko dla ludzi do łatwiejszej identyfikacji numeru. Nadal masz dwa alfabety (duże i małe litery) oraz dziesięć cyfr numerycznych o długości 22 znaków. To 22 ^ (26 * 2 + 10), co równa się 1,6990502e + 83. Albo o liczbie atomów w znanym wszechświecie . Powodzenia w wymuszaniu tego przez HTTP. ;)
Chris Balogh,
Wydaje się, że nie powoduje to unieważnienia tokena odświeżania, który mógłby zostać skradziony przed usunięciem plików cookie (jeśli jest tam przechowywany).
Ondrej Galbavý
1

Działa to w celu wylogowania użytkownika z aplikacji, ale nie Google.

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

Źródło: https://developers.google.com/identity/sign-in/web/sign-in

CamHart
źródło
1
nie spowoduje to całkowitego wylogowania użytkownika z jego konta Google. Niszczy tylko to, AuthInstanceczego użyłeś. Twoje źródło mówi ... „ Możesz umożliwić użytkownikom wylogowanie się z aplikacji bez wylogowywania się z Google ...
Roshana Pitigala,
@RoshanaPitigala zaktualizował odpowiedź, aby określić. Ta odpowiedź jest odpowiedzią na tytuł pytania, ale kiedy przeczytasz bardziej szczegółowo pytanie, zrozumiesz, że tytuł został nieprawidłowo napisany. Ta odpowiedź działa dla każdego, kto trafił tutaj zgodnie z tytułem pytania.
CamHart
1

Ouath sprawia, że ​​instancja Google jest zerowa, a tym samym wyrzucasz ją z Google. Tak właśnie powstaje architektura. Wylogowanie się z Google, jeśli wylogujesz się z aplikacji, jest brudną robotą, ale nie możesz pomóc, jeśli wymóg stanowi to samo. Dlatego dodaj następujący kod do swojej funkcji signOut (). Moim projektem była aplikacja Angular 6:

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

Tutaj localhost: 4200 to adres URL mojej aplikacji. Jeśli Twoja strona logowania to xyz.com, wprowadź to.

Rahul Sharma
źródło
1

ten kod będzie działał, aby się wylogować

    <script>
      function signOut() 
      {
        var auth2 = gapi.auth2.getAuthInstance();
        auth2.signOut().then(function () {   
        console.log('User signed out.');   
        auth2.disconnect();   
      }); 
        auth2.disconnect();
      } 
    </script>
Sai Kiran Manthuri
źródło
1

Aby wylogować się tylko z aplikacji, ale nie z Gmaila:

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.');
            });
        });
    });

Używam powyżej w moim kodzie ReactJs.

Sunil Kumar Singh
źródło
0

Mam nadzieję, że uda nam się to osiągnąć, przechowując token w sesji podczas logowania i uzyskując dostęp do tokena, gdy kliknął wylogowanie.

    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
źródło
0

Wygląda na to, że Google ostatnio zepsuło coś ze swoimi unieważnionymi danymi (zaczęło zwracać dla nas 400 błędów). Teraz musisz zadzwonić

auth2.disconnect ();

W naszym przypadku musimy poczekać kilka sekund na zakończenie połączenia rozłączającego, w przeciwnym razie kod logowania zostanie ponownie autoryzowany, zanim to się stanie. Byłoby dobrze, gdyby Google zwrócił obietnicę z metody rozłączenia.

Sean
źródło