前言
最近想來試試網頁串 google 第三方登入的功能,發現官方文件上有一串敘述,簡單說只要目前串的是 Google Sign-in JavaScript library(https://apis.google.com/js/platform.js )的話,就需要 migrate 到新的 library,目前的 library 在 2023/3/31 後就會淘汰,詳細可以參考這篇:Discontinuing Google Sign-In JavaScript Platform Library for web
在官方文件的選單裡已經分成兩種 web api,這篇主要會分享新版使用 Google 帳戶登入的 api(https://accounts.google.com/gsi/client )
取得 client ID
使用 google 登入 api 需要先有一個 client ID:
到 Google Cloud 新增一個專案(或用現有的專案)
選左邊的憑證 -> 建立憑證 -> OAuth 用戶端 ID
首次設定的話,會需要先設定 OAuth 同意畫面,點「設定同意畫面」按鈕 -> User Type 選擇外部,之後可以填寫必填欄位就好
設定好同意畫面後,預設的狀態會是「測試中」,只有「測試使用者」才有存取權限,所以要記得把自己的 mail 加進去
重新回到剛剛的「建立 OAuth 用戶端 ID」畫面,因為我想要用在網頁登入,所以選擇「網頁應用程式」
我們會先在本機做測試,所以要把 localhost 或其他本地測試網址加到「已授權的 JavaScript 來源」,以 localhost 來說,要分別寫「 http://localhost 」和「 http://localhost:{port} 」
送出後就會拿到 client ID 了~
登入功能
首先在 html 內先引入 api script
<script src="https://accounts.google.com/gsi/client" async defer></script>
接著加入 google 登入按鈕 的程式碼,程式碼的部分可以選擇 html api 或 JS api ,以下使用 html api
<div
id="g_id_onload"
data-client_id="{YOUR_CLIENT_ID}"
data-callback="handleCallback"
data-auto_prompt="false"
></div>
<div
class="g_id_signin"
data-type="standard"
data-size="large"
data-theme="outline"
data-text="sign_in_with"
data-shape="pill"
data-logo_alignment="left"
></div>
第一個 div #g_id_onload
主要是控制資料相關的屬性,參考 g_id_onload 參數
第二個 div .g_id_signin
是控制登入按鈕的顯示,參考 g_id_signin 參數
簡單介紹上面用到的幾個:data-client_id
是剛剛申請的 client ID;data-login_uri
跟 data-callback
二擇一使用,用來告訴 google 拿到憑證之後要做什麼,因為沒有後端的登入 endpoint,這邊先用 data-callback
來實作,我們寫一個 function handleCallback
來處理回傳的憑證,只要登入後有呼叫到這個 callback function 就表示成功登入了,印出憑證內容會得到 clientId
, credential
和 select_by
function handleCallback(response) {
console.log(response);
}
// response
{
"clientId": "726275...uie.apps.googleusercontent.com",
"credential": "eyJhb...",
"select_by": "btn"
}
其中 credential
是 base64 的 JWT Token,可以用解碼的方式拿到使用者資料,這邊用 stackoverflow 找到的 function 來執行
function parseJwt (token) {
var base64Url = token.split('.')[1];
var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
var jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
return JSON.parse(jsonPayload);
};
function handleCallback(response) {
const data = parseJwt(response.credential);
console.log(data);
}
解碼後的資料如下:
// data
{
"iss": "https://accounts.google.com", // The JWT's issuer
"nbf": 161803398874,
"aud": "314159265-pi.apps.googleusercontent.com", // Your server's client ID
"sub": "3141592653589793238", // The unique ID of the user's Google Account
"hd": "gmail.com", // If present, the host domain of the user's GSuite email address
"email": "elisa.g.beckett@gmail.com", // The user's email address
"email_verified": true, // true, if Google has verified the email address
"azp": "314159265-pi.apps.googleusercontent.com",
"name": "Elisa Beckett",
// If present, a URL to user's profile picture
"picture": "https://lh3.googleusercontent.com/a-/e2718281828459045235360uler",
"given_name": "Eliza",
"family_name": "Beckett",
"iat": 1596474000, // Unix timestamp of the assertion's creation time
"exp": 1596477600, // Unix timestamp of the assertion's expiration time
"jti": "abc161803398874def"
}
這樣就完成基本的登入功能了~
如果要在正式環境使用,記得修改以下:
- 到憑證裡「已授權的 JavaScript 來源」加入正式環境的 domain
- 到 Oauth 同意畫面點「發布應用程式」,發布需要通過驗證,需要的內容可以參考官方所列