之前寫的舊版「Google API 處理登入登出功能」,經「Google 官方公告」將於 2023/3/31 終止,如果你的網站使用了「Google API 舊版登入功能」程式碼,到了三月底就不能再運作。
Google 官方提供了將舊版程式碼移轉到新版的操作說明,本篇也會提供各種情況下的實作範例程式碼供參考。
(圖片出處: pexels.com)
一、準備動作
操作 API 之前需要先建立 Google API 專案,如果還沒建立過的話,請完成以下流程:- 「取得 Google API 金鑰流程」→「一、建立專案」
- 「處理 OAuth 憑證」→「二、建立 OAuth 憑證」→「三、設定 OAuth 同意畫面」
二、安裝 Google 預設登入按鈕
1. 說明文件以下頁面為需要瞭解的官方技術文件:- 從 Google 登入遷移:Google 捨棄了原有的 Sign-In API,整合到新版的 Google Identity API。如果曾使用了舊版程式碼,這個頁面列出了新舊程式碼的差異,可以根據說明來調整舊程式碼,或是乾脆全部使用新版程式碼。
- 使用 Google JavaScript API 登入:說明如何使用 JS 操作 API,以及取得 Google 使用者帳號資料後,JWT 的編碼格式為何
<script src="https://accounts.google.com/gsi/client" async defer></script>
<div id="g_id_onload" data-client_id="5432xxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com" data-callback="onSignIn1"></div>
<div class="g_id_signin" data-type="standard"></div>
目前狀態:
<span id="GOOGLE_STATUS_1"></span>
<script>
// 登入之後
function onSignIn1(response) {
var credential = response.credential,
profile = JSON.parse(decodeURIComponent(escape(window.atob(credential.split(".")[1].replace(/-/g, "+").replace(/_/g, "/"))))), // 對 JWT 進行解碼
target = document.getElementById("GOOGLE_STATUS_1"),
html = "";
html += "ID: " + profile.sub + "<br/>";
html += "會員暱稱: " + profile.name + "<br/>";
html += "會員頭像:" + profile.picture + "<br/>";
html += "會員 email:" + profile.email + "<br/>";
target.innerHTML = html;
}
</script>
- 紅色字串請置換為前面「處理 OAuth 憑證」流程取得的「用戶端 ID」
- 程式碼請放在前面「處理 OAuth 憑證」流程設定的網站
<script src="https://accounts.google.com/gsi/client" async defer></script>
<div id="g_id_onload" data-client_id="5432xxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com" data-context="signin" data-ux_mode="popup" data-callback="onSignIn2" data-auto_prompt="false"></div>
<div class="g_id_signin" data-type="standard" data-shape="pill" data-theme="filled_blue" data-text="signin" data-size="large" data-logo_alignment="left"></div>
目前狀態:
<span id="GOOGLE_STATUS_2"></span>
<script>
// 登入之後
function onSignIn2(response) {
var credential = response.credential,
profile = JSON.parse(decodeURIComponent(escape(window.atob(credential.split(".")[1].replace(/-/g, "+").replace(/_/g, "/"))))),
target = document.getElementById("GOOGLE_STATUS_2"),
html = "";
html += "ID: " + profile.sub + "<br/>";
html += "會員暱稱: " + profile.name + "<br/>";
html += "會員頭像:" + profile.picture + "<br/>";
html += "會員 email:" + profile.email + "<br/>";
target.innerHTML = html;
}
</script>
修改參數的方式請參考前面說明,由於 Google 新版登入 API 使用官方按鈕時,HTML 元素強制使用 ID 名稱 "g_id_onload",因此一個頁面只能出現一個按鈕,此處無法再提供「程式碼產生器」的範例效果,請自行複製程式碼在自己的頁面看效果。
三、自訂登入按鈕樣式
1. 初步說明 Google 官方提供的按鈕有一定的格式與大小,雖能調整但彈性不大。如不使用官方按鈕,想要自製「登入」、「登出」的樣式,那麼就得自行處理以下:- 分別製作兩個按鈕
- 分別處理兩個按鈕的點擊
<!--jQuery-->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<!--Bootstrap-->
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<!--登入、登出按鈕-->
<button id="GOOGLE_login" class="btn btn-large btn-primary">GOOGLE 登入</button> <button id="GOOGLE_logout" class="btn btn-large btn-warning">GOOGLE 登出</button>
目前狀態:
<span id="GOOGLE_STATUS_3"></span>
<script src="https://accounts.google.com/gsi/client" async defer></script>
<script>
function startSignIn() {
google.accounts.id.initialize({
client_id: "5432xxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com",
callback: onSignIn3,
prompt_parent_id: "GOOGLE_login" // 設定登入視窗的位置, 若不設定此參數則預設出現在網頁右上角
});
google.accounts.id.prompt((notification) => {
// 如果無法彈出登入視窗 紀錄錯誤訊息
if (notification.isNotDisplayed() || notification.isSkippedMoment()) {
console.log(notification);
}
});
}
// 處理登入取得的資訊
function onSignIn3(response) {
var credential = response.credential,
profile = JSON.parse(decodeURIComponent(escape(window.atob(credential.split(".")[1].replace(/-/g, "+").replace(/_/g, "/"))))),
$target = $("#GOOGLE_STATUS_3"),
html = "";
html += "ID: " + profile.sub + "<br/>";
html += "會員暱稱: " + profile.name + "<br/>";
html += "會員頭像:" + profile.picture + "<br/>";
html += "會員 email:" + profile.email + "<br/>";
$target.html(html);
}
// 點擊登入
$("#GOOGLE_login").click(function() {
// 進行登入程序
startSignIn();
});
// 點擊登出
$("#GOOGLE_logout").click(function() {
google.accounts.id.disableAutoSelect();
// 登出後的動作
$("#GOOGLE_STATUS_3").html("已登出");
});
</script>
主要修改地方為紅字的「用戶端 ID」,也可修改點擊按鈕後要處理的 JS,其餘注意事項請參考前面範例。
下面是「自製登入登出按鈕」的範例效果,可進行操作並注意對應狀態的文字:
目前狀態:
操作「Google JavaScript API 登入」可能會遇到幾個問題:
3. One Tap 使用者體驗請參考官網說明「瞭解 One Tap 使用者體驗」,新版 Google Identity API 讓使用者可以暫時停用「Google One 登入」功能,如果彈出登入視窗時,使用者曾經按右上角的「X」圖示進行關閉,則將會有一段時間無法開啟登入功能。所以開發者在測試登入按鈕時,有可能會發生怎麼點都無法執行程式的狀況,我也是研究很久才發現此事,要等過了幾小時冷卻後才能重新執行。至於要等待多久,請見該頁面官方提供的表格整理,從 2 小時到數週都有可能。這個功能雖可提升使用者體驗,但對開發者就不太友善了,所以程式碼裡面最好加入「偵測無法彈出登入視窗」的功能,請參考官方文件,或是上面提供的範例程式碼可找到相關的註解說明。
我找到一個方法可以立即終止冷卻期,適合開發者使用:
- 進入冷卻期後可使用官方登入按鈕,例如本篇「二、安裝 Google 預設登入按鈕」那一個按鈕
- 完成登入後,再測試自訂按鈕,例如本篇「三、自訂登入按鈕樣式」的按鈕,就可看到效果了
- https://www.googleapis.com/auth/userinfo.email
- https://www.googleapis.com/auth/userinfo.profile
更多 Google 相關文章: