Bagaimana saya bisa memverifikasi token akses API otentikasi Google?

134

Bagaimana saya bisa memverifikasi token akses otentikasi Google?

Saya perlu entah bagaimana menanyakan Google dan bertanya: Apakah [diberi token akses] valid untuk akun Google [[email protected]]?

Versi singkat :
Jelas bagaimana token akses yang disediakan melalui Api Otentikasi Google :: Otentikasi OAuth untuk Aplikasi Web dapat digunakan untuk kemudian meminta data dari berbagai layanan Google. Tidak jelas bagaimana memeriksa apakah token akses yang diberikan valid untuk akun Google yang diberikan. Saya ingin tahu caranya.

Versi panjang :
Saya sedang mengembangkan API yang menggunakan otentikasi berbasis token. Token akan dikembalikan setelah penyediaan nama pengguna + kata sandi yang valid atau setelah pemberian token pihak ketiga dari salah satu layanan N yang dapat diverifikasi.

Salah satu layanan pihak ketiga adalah Google, yang memungkinkan pengguna untuk mengautentikasi terhadap layanan saya menggunakan akun Google mereka. Ini nantinya akan diperluas untuk mencakup akun Yahoo, penyedia OpenID tepercaya dan sebagainya.

Contoh skematis akses berbasis Google:

alt teks http://webignition.net/images/figures/auth_figure002.png

Entitas 'API' berada di bawah kendali penuh saya. Entitas 'antarmuka publik' adalah aplikasi berbasis web atau desktop. Beberapa antarmuka publik berada di bawah kendali saya, yang lain tidak akan dan yang lain mungkin saya bahkan tidak pernah tahu.

Karenanya saya tidak bisa mempercayai token yang disediakan untuk API pada langkah 3. Ini akan diberikan bersama dengan alamat email akun Google yang sesuai.

Saya perlu menanyakan Google dan bertanya: Apakah token akses ini valid untuk [email protected] ?

Dalam hal ini, [email protected] adalah pengidentifikasi unik akun Google - alamat email yang digunakan seseorang untuk masuk ke akun Google mereka. Ini tidak dapat dianggap sebagai alamat Gmail - seseorang dapat memiliki akun Google tanpa memiliki akun Gmail.

Dokumentasi Google dengan jelas menyatakan bagaimana, dengan token akses, data dapat diambil dari sejumlah layanan Google. Tampaknya tidak ada yang menyatakan bagaimana Anda dapat memeriksa apakah token akses yang diberikan valid pada awalnya.

Perbarui token ini valid untuk N layanan Google. Saya tidak dapat mencoba token terhadap layanan Google sebagai cara memverifikasi karena saya tidak akan tahu subset dari semua layanan Google yang benar-benar digunakan oleh pengguna tertentu.

Selain itu, saya tidak akan pernah menggunakan token akses autentikasi Google untuk mengakses layanan Google apa pun, hanya sebagai sarana memverifikasi yang seharusnya pengguna Google adalah siapa yang mereka katakan. Jika ada cara lain untuk melakukan ini, saya senang untuk mencoba.

Jon Cram
sumber
Layanan auth spesifik apa yang menjadi pertanyaan ini (OAuth, AuthSub, Aplikasi Terpasang, ...)? Harap berikan tautan yang lebih detail.
Martin v. Löwis
@ Martin v. Löwis: Layanan 'OAuth Authentication for Web Applications' - Saya telah memperbarui awal pertanyaan untuk mencerminkan hal ini. Terima kasih telah menunjukkan ini!
Jon Cram
artikel menarik tentang verifikasi kunci google dapat memberikan lebih banyak grup
insight.google.com/group/Google-Maps-API/msg/f9e3c5ad3cbda4d7

Jawaban:

138

Untuk pemeriksaan pengguna, poskan saja mendapatkan token akses sebagai accessToken dan poskan dan dapatkan responsnya

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

Anda dapat mencoba di bilah alamat di browser juga, gunakan httppost dan respons di java juga

tanggapan akan seperti

{
     "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"
    }

Ruang lingkup adalah izin yang diberikan oleh accessToken. Anda dapat memeriksa id lingkup di tautan ini

Perbarui: Posting API baru seperti di bawah ini

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

Respons akan sama

 {
 // 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"
}

Untuk info lebih lanjut, https://developers.google.com/identity/sign-in/android/backend-auth

Vinoj John Hosan
sumber
11
Ada versi yang lebih baru untuk oauth2 google - v3. Lihat contoh di sini: developers.google.com/identity/sign-in/android/backend-auth
AlikElzin-kilaka
30

Anda dapat memverifikasi token akses otentikasi Google dengan menggunakan titik akhir ini:

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

Ini adalah Google V3 OAuth AccessToken yang memvalidasi titik akhir, Anda dapat merujuk dari dokumen Google di bawah ini: (Di OAUTH 2.0 ENDPOINTSTab)

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

Nick Tsai
sumber
Untuk dokumentasi Backend - sumber dokumentasi ada di sini
eton_ceb
26

Ok, sebagian besar jawaban valid tetapi tidak tepat. Gagasan JWT adalah Anda dapat memvalidasi token tanpa perlu menghubungi penerbit setiap saat. Anda harus memeriksa id dan memverifikasi tanda tangan token dengan kunci publik yang dikenal dari sertifikat yang digunakan Google untuk menandatangani token.

Lihat posting selanjutnya mengapa dan bagaimana melakukan ini.

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

Remco
sumber
3
Tolong, lebih banyak upvotes! The idea of JWT is that you can validate the token without the need to contact the issuer everytime.
Moritz Schmitz v. Hülst
Iya! ppl sedang melakukan google jika mereka hanya memanggil google untuk info token
datdinhquoc
Anda tidak dapat melakukan ini dengan token akses Google karena mereka bukan JWT. Periksa stackoverflow.com/questions/48623656/…
DanielJaramillo
18
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
sumber
2
Jawaban ini hampir masih valid. Namun Issued_to tampaknya tidak disetel lagi. developers.google.com/accounts/docs/…
frostymarvelous
6

Tanggapan aliran kode Google oauth selain access_tokenjuga mengembalikan id_tokenyang berisi berguna untuk info validasi dalam bentuk terenkripsi.

Satu hal yang membuat token ID berguna adalah kenyataan bahwa Anda dapat membagikannya di berbagai komponen aplikasi Anda. Komponen-komponen ini dapat menggunakan token ID sebagai mekanisme otentikasi ringan yang mengotentikasi aplikasi dan pengguna. Tetapi sebelum Anda dapat menggunakan informasi dalam token ID atau mengandalkannya sebagai penegasan bahwa pengguna telah mengautentikasi, Anda harus memvalidasinya.

Validasi token ID memerlukan beberapa langkah:

  • Verifikasi bahwa token ID adalah JWT yang ditandatangani dengan benar dengan kunci publik Google yang sesuai.
  • Verifikasi bahwa nilai aud dalam token ID sama dengan ID klien aplikasi Anda.
  • Verifikasi bahwa nilai iss dalam token ID sama dengan accounts.google.com atau https://accounts.google.com .
  • Verifikasi bahwa waktu kadaluwarsa (exp) token ID belum berlalu.
  • Jika Anda melewatkan parameter hd dalam permintaan, verifikasi bahwa token ID memiliki klaim hd yang cocok dengan domain yang dihosting Google Apps Anda.

https://developers.google.com/identity/protocols/OpenIDConnect#validatinganidtoken tautan memiliki sampel kode untuk validasi token ID.

Lihat juga /security/37818/why-use-openid-connect-instead-of-plain-oauth .

Vadzim
sumber
1

Saya perlu menanyakan Google dan bertanya: Apakah token akses ini valid untuk [email protected]?

Tidak. Yang Anda butuhkan hanyalah meminta login standar dengan Login Federasi untuk Pengguna Akun Google dari domain API Anda. Dan hanya setelah itu Anda dapat membandingkan "ID pengguna persisten" dengan yang Anda miliki dari 'antarmuka publik'.

Nilai ranah digunakan pada halaman Google Federated Login untuk mengidentifikasi situs yang meminta kepada pengguna. Ini juga digunakan untuk menentukan nilai ID pengguna persisten yang dikembalikan oleh Google.

Jadi, Anda harus dari domain yang sama dengan 'antarmuka publik'.

Dan jangan lupa bahwa pengguna perlu memastikan bahwa API Anda dapat dipercaya;) Jadi Google akan bertanya kepada pengguna apakah itu memungkinkan Anda untuk memeriksa identitasnya.

Malx
sumber
1

Berikut ini contoh menggunakan 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
sumber
0

Coba buat permintaan terautentikasi OAuth menggunakan token Anda ke https://www.google.com/accounts/AuthSubTokenInfo . Ini hanya didokumentasikan agar berfungsi untuk AuthSub, tetapi berfungsi juga untuk OAuth. Itu tidak akan memberi tahu Anda untuk siapa pengguna token itu, tetapi ia akan memberi tahu Anda layanan mana yang sah untuknya, dan permintaan itu akan gagal jika token tidak sah atau telah dicabut.

Jonathan
sumber
0

Token akses OAuth yang sewenang-wenang tidak dapat digunakan untuk otentikasi, karena makna token tersebut di luar spesifikasi OAuth Core. Ini dapat dimaksudkan untuk penggunaan tunggal atau jendela kedaluwarsa yang sempit, atau dapat memberikan akses yang tidak ingin diberikan oleh pengguna. Ini juga buram, dan konsumen OAuth yang memperolehnya mungkin tidak pernah melihat jenis pengenal pengguna.

Penyedia layanan OAuth dan satu atau lebih konsumen dapat dengan mudah menggunakan OAuth untuk memberikan token otentikasi yang dapat diverifikasi, dan ada proposal dan ide untuk melakukan ini di luar sana, tetapi penyedia layanan sewenang-wenang yang hanya berbicara OAuth Core tidak dapat menyediakan ini tanpa kerjasama lain. pentahbisan dengan konsumen. Metode REST AuthSubTokenInfo khusus Google, bersama dengan pengidentifikasi pengguna, sudah dekat, tetapi tidak cocok, karena dapat membatalkan token, atau token dapat kedaluwarsa.

Jika Google ID Anda adalah pengidentifikasi OpenId, dan 'antarmuka publik' Anda adalah aplikasi web atau dapat memanggil browser pengguna, maka Anda mungkin harus menggunakan OpenID OP Google.

OpenID terdiri dari hanya mengirim pengguna ke OP dan mendapatkan kembali pernyataan yang ditandatangani. Interaksi ini semata-mata untuk kepentingan RP. Tidak ada token yang berumur panjang atau pegangan khusus pengguna lainnya yang dapat digunakan untuk menunjukkan bahwa RP telah berhasil mengotentikasi pengguna dengan OP.

Salah satu cara untuk memverifikasi otentikasi sebelumnya terhadap pengidentifikasi OpenID adalah dengan hanya melakukan otentikasi lagi, dengan asumsi agen-pengguna yang sama sedang digunakan. OP harus dapat mengembalikan pernyataan positif tanpa interaksi pengguna (dengan memverifikasi cookie atau sertifikat klien, misalnya). OP bebas untuk meminta interaksi pengguna lain, dan mungkin akan terjadi jika permintaan otentikasi datang dari domain lain (OP saya memberi saya opsi untuk mengautentikasi ulang RP khusus ini tanpa berinteraksi di masa mendatang). Dan dalam kasus Google, UI yang dilalui pengguna untuk mendapatkan token OAuth mungkin tidak menggunakan pengidentifikasi sesi yang sama, sehingga pengguna harus mengautentikasi ulang. Tetapi bagaimanapun, Anda akan dapat menegaskan identitas.

Karl Anderson
sumber
OpenID 2.0 telah ditinggalkan dan dinonaktifkan oleh Google demi OpenID Connect berbasis OAuth yang menyediakan token id yang dapat diverifikasi .
Vadzim