4 月 262023
 

Source: 網頁版 Google OAuth 的作法

早期的作法是「Integrating Google Sign-In into your web app」這個,但官方已經標注 deprecated 了,在官方的文件上面可以看到對應的警告說明,現在雖然會動,但之後應該會關掉:

Warning: The support of Google Sign-In JavaScript platform library for Web is set to be deprecated after March 31, 2023. The solutions in this guide are based on this library and therefore also deprecated.

本來一開始是走「OAuth 2.0 for Client-side Web Applications」這個,這份文件會教你引入 Google 提供的 javascript library,也就是 https://apis.google.com/js/api.js 這份,但其實沒必要這樣用… 先不管會多吃多少資源,比較敏感的是隱私問題 (像是透過 3rd-party cookie 追蹤)。

後來研究出來比較好的方法是走「Using OAuth 2.0 for Web Server Applications」這邊提到的方式,就算是 javascript 也可以建立出來,像是這樣:

(() => {
  const el = document.getElementById('glogin');
  el.addEventListener('click', () => {
    document.location = 'https://accounts.google.com/o/oauth2/v2/auth?' +
      'client_id=x-x.apps.googleusercontent.com' +
      '&redirect_uri=https://test.example.com/google_redirect_uri.php' +
      '&response_type=code' +
      '&scope=profile+email';
  });
})();

然後這邊的接收端 (google_redirect_uri.php) 是讓 Google 授權後用 redirect 的方式把對應的認證變數 code 帶過來,這邊是用 PHP 實做,有兩個步驟:

  • 先用 POST 打 https://oauth2.googleapis.com/token 取得 (換得) access token,也就是 access_token
  • 再用 GET 打 https://www.googleapis.com/oauth2/v3/userinfo (帶上一個取得的 access token 進去) 取得使用者資料。

scope 裡如果沒有 email 的話,最後就不會拿到 email,但 SSO 應用應該會需要這個資訊,所以範例裡面還是放進去…

這邊是故意儘量用 PHP 內建的 library 實做,但應該不算複雜,換用 Guzzle 或是用其他語言應該算簡單:

$qs = http_build_query([
    'code' => $_GET['code'],
    'client_id' => 'x-x.apps.googleusercontent.com',
    'client_secret' => 'x',
    'redirect_uri' => 'https://test.example.com/google_redirect_uri.php',
    'grant_type' => 'authorization_code',
]);

$url = 'https://oauth2.googleapis.com/token';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $qs);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$res = curl_exec($ch);
curl_close($ch);

$data = json_decode($res);

$atoken = $data->access_token;

$url = 'https://www.googleapis.com/oauth2/v3/userinfo';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer ${atoken}"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$res = curl_exec($ch);
curl_close($ch);

最後的資料就在 $res 裡面,想要看可以直接用 var_dump($res); 看。

這樣只有使用者真的要用 Google SSO 時才會有 request 進到 Google 伺服器。

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

CAPTCHA Image
Play CAPTCHA Audio
Reload Image