Jak mogę zweryfikować token dostępu API uwierzytelniania Google?

145

Jak mogę zweryfikować token dostępu do uwierzytelniania Google?

Muszę w jakiś sposób zapytać Google i zapytać: Czy [dany token dostępu] jest ważny dla konta Google [[email protected]]?

Wersja skrócona :
jest jasne, w jaki sposób token dostępu dostarczany przez Google Authentication Api :: OAuth Authentication for Web Applications może być następnie używany do żądania danych z szeregu usług Google. Nie jest jasne, jak sprawdzić, czy dany token dostępu jest ważny dla danego konta Google. Chciałbym wiedzieć, jak to zrobić.

Wersja długa :
opracowuję interfejs API, który używa uwierzytelniania opartego na tokenach. Token zostanie zwrócony po podaniu prawidłowej nazwy użytkownika i hasła lub po dostarczeniu tokena strony trzeciej z jednej z N weryfikowalnych usług.

Jedną z usług innych firm będzie Google, umożliwiająca użytkownikowi uwierzytelnianie w mojej usłudze przy użyciu konta Google. Później zostanie to rozszerzone o konta Yahoo, zaufanych dostawców OpenID i tak dalej.

Schematyczny przykład dostępu przez Google:

tekst alternatywny http://webignition.net/images/figures/auth_figure002.png

Podmiot „API” jest pod moją pełną kontrolą. Podmiotem „interfejsu publicznego” jest dowolna aplikacja internetowa lub komputerowa. Niektóre interfejsy publiczne są pod moją kontrolą, inne nie, ao innych jeszcze nigdy się nie dowiem.

Dlatego nie mogę ufać tokenowi dostarczonemu do API w kroku 3. Zostanie on dostarczony wraz z odpowiednim adresem e-mail konta Google.

Muszę w jakiś sposób zapytać Google i zapytać: czy ten token dostępu jest ważny na przykł[email protected] ?

W tym przypadku [email protected] jest unikatowym identyfikatorem konta Google - adresem e-mail, którego ktoś używa do logowania się na swoje konto Google. Nie można założyć, że jest to adres Gmail - ktoś może mieć konto Google bez konta Gmail.

Dokumentacja Google jasno określa, w jaki sposób za pomocą tokena dostępu można pobrać dane z szeregu usług Google. Nic nie wskazuje na to, jak można sprawdzić, czy dany token dostępu jest ważny.

Aktualizacja Token jest ważny dla N usług Google. Nie mogę wypróbować tokena w usłudze Google w celu jej weryfikacji, ponieważ nie będę wiedział, z jakiego podzbioru wszystkich usług Google faktycznie korzysta dany użytkownik.

Ponadto nigdy nie będę używał tokena dostępu uwierzytelniania Google do uzyskiwania dostępu do jakichkolwiek usług Google, a jedynie jako środek do weryfikacji, czy domniemany użytkownik Google jest tym, za kogo się podaje. Jeśli istnieje inny sposób, z przyjemnością spróbuję.

Jon Cram
źródło
Jakiej konkretnej usługi uwierzytelniania dotyczy to pytanie (OAuth, AuthSub, zainstalowane aplikacje, ...)? Podaj bardziej szczegółowy link.
Martin przeciwko Löwis,
@Martin v. Löwis: Usługa „Uwierzytelnianie OAuth dla aplikacji internetowych” - zaktualizowałem początek pytania, aby to odzwierciedlić. Dzięki za zwrócenie uwagi!
Jon Cram,
ciekawy artykuł o weryfikacji klucza Google może dać więcej wglądu groups.google.com/group/Google-Maps-API/msg/f9e3c5ad3cbda4d7
dotjoe

Odpowiedzi:

147

Aby sprawdzić użytkownika, po prostu opublikuj otrzymanie tokenu dostępu jako accessToken i opublikuj go, a otrzymasz odpowiedź

https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=accessToken

możesz spróbować również w pasku adresu w przeglądarkach, użyj httppost i odpowiedzi w java

odpowiedź będzie jak

{
     "issued_to": "xxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com",
     "audience": "xxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com",
     "user_id": "xxxxxxxxxxxxxxxxxxxxxxx",
     "scope": "https://www.googleapis.com/auth/userinfo.profile https://gdata.youtube.com",
     "expires_in": 3340,
     "access_type": "offline"
    }

Zakres to dane uprawnienie accessToken. możesz sprawdzić identyfikatory zakresów w tym linku

Aktualizacja: nowy post API, jak poniżej

https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123

Odpowiedź będzie taka jak

 {
 // These six fields are included in all Google ID Tokens.
 "iss": "https://accounts.google.com",
 "sub": "110169484474386276334",
 "azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "iat": "1433978353",
 "exp": "1433981953",

 // These seven fields are only included when the user has granted the "profile" and
 // "email" OAuth scopes to the application.
 "email": "[email protected]",
 "email_verified": "true",
 "name" : "Test User",
 "picture": "https://lh4.googleusercontent.com/-kYgzyAWpZzJ/ABCDEFGHI/AAAJKLMNOP/tIXL9Ir44LE/s99-c/photo.jpg",
 "given_name": "Test",
 "family_name": "User",
 "locale": "en"
}

Aby uzyskać więcej informacji, https://developers.google.com/identity/sign-in/android/backend-auth

Vinoj John Hosan
źródło
12
Dostępna jest nowsza wersja Google oauth2 - v3. Zobacz przykład tutaj: developers.google.com/identity/sign-in/android/backend-auth
AlikElzin-kilaka
-1 „Nie nadaje się do użycia w kodzie produkcyjnym, ponieważ żądania mogą być ograniczane lub w inny sposób podlegać sporadycznym błędom”. developers.google.com/identity/sign-in/ios/… Odpowiedź Remco jest prawidłowa
Heinzlmaen
34

możesz zweryfikować token dostępu do uwierzytelniania Google, korzystając z tego punktu końcowego:

https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=<access_token>

To jest punkt końcowy walidacji tokena dostępu Google V3 OAuth, możesz zapoznać się z dokumentem Google poniżej: (Na OAUTH 2.0 ENDPOINTSkarcie)

https://developers.google.com/identity/protocols/OAuth2UserAgent#validate-access-token

Nick Tsai
źródło
Dokumentacja Backend - źródło dokumentacji jest tutaj
eton_ceb
32

Ok, większość odpowiedzi jest poprawna, ale nie do końca. Ideą JWT jest to, że możesz zweryfikować token bez konieczności kontaktowania się z wydawcą za każdym razem. Musisz sprawdzić identyfikator i zweryfikować podpis tokena za pomocą znanego klucza publicznego certyfikatu, którego Google użył do podpisania tokena.

Zobacz następny post, dlaczego i jak to zrobić.

http://ncona.com/2015/02/consuming-a-google-id-token-from-a-server/

Remco
źródło
4
Poproszę o więcej głosów za! The idea of JWT is that you can validate the token without the need to contact the issuer everytime.
Moritz Schmitz v. Hülst
1
tak! ppl są ddos-ingiem Google, jeśli po prostu dzwonią do Google po informacje o
tokenach
1
Nie możesz tego zrobić za pomocą tokenów dostępu Google, ponieważ nie są to tokeny JWT. Sprawdź stackoverflow.com/questions/48623656/…
DanielJaramillo
@DanielJaramillo Dzięki za wgląd. Część id jest w rzeczywistości weryfikowalnym jwt. Punkt nadal stoi. Weryfikacja offline to tutaj główna idea.
Remco
19
function authenticate_google_OAuthtoken($user_id)
{
    $access_token   = google_get_user_token($user_id); // get existing token from DB
    $redirecturl    = $Google_Permissions->redirecturl;
    $client_id      = $Google_Permissions->client_id;
    $client_secret  = $Google_Permissions->client_secret;
    $redirect_uri   = $Google_Permissions->redirect_uri;
    $max_results    = $Google_Permissions->max_results;

    $url = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token='.$access_token;
    $response_contacts  =  curl_get_responce_contents($url);
    $response   =   (json_decode($response_contacts));

    if(isset($response->issued_to))
    {
        return true;
    }
    else if(isset($response->error))
    {
        return false;
    }
}
ahmed
źródło
2
Ta odpowiedź jest prawie nadal aktualna. Wydaje się jednak, że Issued_to nie jest już ustawione. developers.google.com/accounts/docs/…
frostymarvellous
Dzięki stary… zaoszczędziłeś dużo czasu.
Arunjith RS
8

Odpowiedź Google oauth przepływu kodu oprócz access_tokenzwrotów id_tokenzawiera przydatne do weryfikacji informacje w postaci zaszyfrowanej.

Jedną z rzeczy, która sprawia, że ​​tokeny identyfikacyjne są przydatne, jest fakt, że można je przekazywać między różnymi komponentami aplikacji. Te składniki mogą używać tokenu identyfikatora jako lekkiego mechanizmu uwierzytelniania uwierzytelniającego aplikację i użytkownika. Ale zanim będziesz mógł użyć informacji w tokenie identyfikatora lub polegać na nich jako na potwierdzeniu, że użytkownik został uwierzytelniony, musisz je zweryfikować.

Weryfikacja tokena identyfikatora wymaga kilku kroków:

  • Sprawdź, czy token identyfikacyjny to JWT, który jest poprawnie podpisany odpowiednim kluczem publicznym Google.
  • Sprawdź, czy wartość aud w tokenie identyfikatora jest równa identyfikatorowi klienta aplikacji.
  • Sprawdź, czy wartość iss w tokenie identyfikatora jest równa accounts.google.com lub https://accounts.google.com .
  • Sprawdź, czy nie upłynął czas wygaśnięcia (exp) tokenu identyfikatora.
  • Jeśli w żądaniu przekazałeś parametr hd, sprawdź, czy token identyfikatora zawiera żądanie hd zgodne z domeną hostowaną w Google Apps.

Link https://developers.google.com/identity/protocols/OpenIDConnect#validatinganidtoken zawiera przykłady kodu do weryfikacji tokenów identyfikacyjnych.

Zobacz też /security/37818/why-use-openid-connect-instead-of-plain-oauth .

Vadzim
źródło
1

Muszę w jakiś sposób zapytać Google i zapytać: czy ten token dostępu jest ważny na przykł[email protected]?

Nie. Wszystko, czego potrzebujesz, to poproś o standardowe logowanie za pomocą sfederowanego logowania dla użytkowników kont Google z domeny API. Dopiero potem możesz porównać „stały identyfikator użytkownika” z tym, który masz z „interfejsu publicznego”.

Wartość realm jest używana na stronie Google Federated Login do identyfikacji żądającej witryny dla użytkownika. Służy również do określenia wartości trwałego identyfikatora użytkownika zwróconego przez Google.

Musisz więc należeć do tej samej domeny, co „interfejs publiczny”.

I nie zapominaj, że użytkownik musi mieć pewność, że Twoje API może być zaufane;) Więc Google zapyta użytkownika, czy pozwala sprawdzić jego tożsamość.

Malx
źródło
1

Oto przykład użycia Guzzle :

/**
 * @param string $accessToken JSON-encoded access token as returned by \Google_Client->getAccessToken() or raw access token
 * @return array|false False if token is invalid or array in the form
 * 
 * array (
 *   'issued_to' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com',
 *   'audience' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com',
 *   'scope' => 'https://www.googleapis.com/auth/calendar',
 *   'expires_in' => 3350,
 *   'access_type' => 'offline',
 * )
 */
public static function tokenInfo($accessToken) {
    if(!strlen($accessToken)) {
        return false;
    }

    if($accessToken[0] === '{') {
        $accessToken = json_decode($accessToken)->access_token;
    }

    $guzzle = new \GuzzleHttp\Client();

    try {
        $resp = $guzzle->get('https://www.googleapis.com/oauth2/v1/tokeninfo', [
            'query' => ['access_token' => $accessToken],
        ]);
    } catch(ClientException $ex) {
        return false;
    }

    return $resp->json();
}
mpen
źródło
1
  1. Zgodnie z dokumentacją Google , powinieneś użyć biblioteki klienta AP Google, która sprawia, że ​​jest to (weryfikacja tokena, wyodrębnianie roszczeń itp.) Znacznie łatwiejsze niż pisanie własnego niestandardowego kodu.

  2. Z punktu widzenia wydajności token powinien być analizowany lokalnie bez ponownego wywoływania Google. Oczywiście potrzebny jest klucz publiczny Google, a pobieranie tego klucza odbywa się przy użyciu strategii buforowania, zaimplementowanej w bibliotece klienta Google od punktu 1 powyżej.

  3. FYI only. Google używa również tokena JWT. Zobacz obrazek poniżej w celach informacyjnych.

wprowadź opis obrazu tutaj

Vikram Rawat
źródło
0

Spróbuj wysłać żądanie uwierzytelnione przez OAuth przy użyciu tokena na stronie https://www.google.com/accounts/AuthSubTokenInfo . Udokumentowano, że działa to tylko w przypadku AuthSub, ale działa również w przypadku OAuth. Nie powie ci, dla którego użytkownika jest token, ale powie ci, dla których usług jest ważny, a żądanie zakończy się niepowodzeniem, jeśli token jest nieprawidłowy lub został unieważniony.

Jonathan
źródło
0

Do uwierzytelnienia nie można użyć dowolnego tokenu dostępu OAuth, ponieważ znaczenie tego tokenu jest poza specyfikacją OAuth Core. Może być przeznaczony do jednorazowego użytku lub z wąskim okresem ważności, lub może zapewniać dostęp, którego użytkownik nie chce udzielić. Jest również nieprzejrzysty, a konsument OAuth, który go uzyskał, mógł nigdy nie zobaczyć żadnego typu identyfikatora użytkownika.

Dostawca usług OAuth i jeden lub więcej konsumentów mogliby z łatwością użyć OAuth, aby zapewnić weryfikowalny token uwierzytelniający, a istnieją propozycje i pomysły, aby to zrobić, ale dowolny dostawca usług mówiący tylko o ordynacja z konsumentem. Specyficzna dla Google metoda REST AuthSubTokenInfo, wraz z identyfikatorem użytkownika, jest bliska, ale również nie jest odpowiednia, ponieważ może unieważnić token lub token może utracić ważność.

Jeśli Twój identyfikator Google jest identyfikatorem OpenId, a Twój „interfejs publiczny” to aplikacja internetowa lub może wywołać przeglądarkę użytkownika, prawdopodobnie powinieneś użyć OpenID OP firmy Google.

OpenID polega po prostu na wysłaniu użytkownika do OP i odzyskaniu podpisanego potwierdzenia. Interakcja jest wyłącznie na korzyść RP. Nie ma trwałego tokenu ani innego uchwytu specyficznego dla użytkownika, którego można by użyć do wskazania, że ​​RP pomyślnie uwierzytelnił użytkownika za pomocą OP.

Jednym ze sposobów zweryfikowania poprzedniego uwierzytelnienia względem identyfikatora OpenID jest po prostu ponowne przeprowadzenie uwierzytelnienia, zakładając, że używany jest ten sam agent użytkownika. OP powinien być w stanie zwrócić pozytywne potwierdzenie bez interakcji użytkownika (na przykład poprzez weryfikację pliku cookie lub certyfikatu klienta). OP może wymagać interwencji innego użytkownika i prawdopodobnie tak się stanie, jeśli żądanie uwierzytelnienia pochodzi z innej domeny (mój OP daje mi opcję ponownego uwierzytelnienia tego konkretnego RP bez interakcji w przyszłości). W przypadku Google interfejs użytkownika, przez który przeszedł użytkownik, aby uzyskać token OAuth, może nie używać tego samego identyfikatora sesji, więc użytkownik będzie musiał ponownie uwierzytelnić się. Ale w każdym razie będziesz mógł potwierdzić tożsamość.

Karl Anderson
źródło
OpenID 2.0 został ostatnio wycofany i wyłączony przez Google na rzecz opartego na OAuth OpenID Connect, który zapewnia weryfikowalne tokeny identyfikatorów .
Vadzim