2023 年底前幾個月收到 FB 給開發人員的通知,提醒「登入 API」要完成「商家驗證」,否則使用權限會受到影響。果然進入 2024 後本站的「會員系統」因為使用了 FB 登入,立刻收到讀者回應,說會顯示 "應用程式錯誤"無法進行註冊。
雖去年事先想處理此事,但看過「FB 官方文件」發現,商家驗證需要提供 "公司登記執照"、"營利事業登記證"、"政府核發的營業稅務文件"...等相關資料,沒有開公司的話根本無能為力。
查了一些資料,例如「想要串接整合 Facebook 登入/註冊功能?你得先進行 Facebook 商家驗證。」,可以確定對於 "個人"開發者而言,想使用 FB 登入 API 已是死路一條,只能研究如何用 Google API 來取代。
由於 2024 Google 登入 API 也有一些變革,要做到跟 FB 一樣能自動登入也不是那麼容易的事,請見本篇的心得整理與實作範例。
(圖片出處: pixabay.com)
一、Google 登入 API 說明
1. 2023 Google 登入去年 Google 登入功能有一次重大變革,通知開發人員 API 必須由原本的「Google Sign-In 移轉為 Google Identity Services(GIS)」。因為操作方式及語法變化很大,已將實作範例程式碼整理到這篇「2023 新版 Google 登入 API」。 2. 2024 Google 登入今年 2024 有使用 Google 登入功能(GIS)的開發人員,都會收到這個「不使用第三方 cookie」的通知,對於操作 API 有稍微的變更,簡單摘要如下:- 為了改善使用者隱私,Chrome 瀏覽器會逐步不使用第三方 cookie
- 登入時瀏覽器會顯示使用者提示
- 參照「遷移網頁應用程式」這部份的內容,程式碼中有些方法會受到影響,例如 isDisplayMoment()、isDisplayed()、isNotDisplayed()、getNotDisplayedReason()、getSkippedReason()...
- 使用官方預設按鈕,點擊後可彈出登入視窗
- 使用自訂按鈕,也許是不能使用 cookie 的關係,無法正常執行、彈出登入視窗
二、Google API 如何自動登入
Google 登入功能(GIS)預設不使用「自動登入」效果,然而各大網站的會員都能自動登入,若本站讓會員每次都要手動點個幾下才能登入,著實是非常不友善的設計。為了實現以往使用「FB 登入 API」的自動登入效果,得詳細研究 Google 官方操作文件。 1. 為何 Google 無法自動登入經過我的實測,使用官方預設按鈕登入,而且啟動「自動登入」的設定,但發現重整頁面後,仍然不會記憶我上次登入的帳號,這讓我十分納悶。 後來找到官方「自動登入及登出」的說明:自動登入必須符合下列條件...使用者必須先登入自己的 Google 帳戶...同意與您的應用程式分享帳戶設定檔...如果使用者有多個 Google 帳戶,而且造訪您的網站,就必須先登入單一 Google 帳戶,並提供該帳戶的同意聲明。終於找到原因了,原來我的瀏覽器有多個 Google 帳號,可能現在 Google 決定不使用第三方 cookie,導致無法記憶上一次登入的帳號,那麼當我有多個 Google 帳號時,就無法自動登入了。除非我把 Google 帳號登出到只剩一個帳號,這樣才能實現「自動登入」... 對於這樣的結果我當然無法接受,哪有辦法告訴所有會員,必須先登出其他 Google 帳號才能自動登入,因此繼續研究解決方案。 2. 研究官方文件根據官網文件「使用 Google JavaScript API 登入」,可用來實作自動登入的參數有這些:
- auto_select: 設定為 true 可以啟用自動選取功能 → 前面有提到,當使用者有多個 Google 帳號時,登入功能依然無法判定如何自動選取
- login_hint: 如果設定了特定數值,例如 Google 帳號 email,就能自動選取該帳號執行登入
三、實作範例
1. 準備動作操作 API 之前需要先建立 Google API 專案,如果還沒建立過的話,請完成以下流程:- 「取得 Google API 金鑰流程」→「一、建立專案」
- 「處理 OAuth 憑證」→「二、建立 OAuth 憑證」→「三、設定 OAuth 同意畫面」
<!--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" />
<!--登入、登出按鈕-->
<div id="GOOGLE_login"><button class="btn btn-large btn-primary">GOOGLE 登入</button></div>
<div id="GOOGLE_logout"><button class="btn btn-large btn-warning">GOOGLE 登出</button></div>
目前狀態:
<div id="GOOGLE_status"></div>
<script>
let autoLoginGoogleAccount = localStorage.autoLoginGoogleAccount || ""; // 自動登入儲存的帳號
let $status = $("#GOOGLE_status");
function init() {
$.getScript("https://accounts.google.com/gsi/client", function () {
// 進行登入程序
startLogin();
});
}
// 進行登入程序
function startLogin() {
google.accounts.id.initialize({
client_id: "5432xxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com",
callback: onLogin,
prompt_parent_id: "GOOGLE_login", // 設定登入視窗的位置, 若不設定此參數則預設出現在網頁右上角
auto_select: true, // 自動登入
login_hint: autoLoginGoogleAccount // 自動登入儲存的帳號
});
google.accounts.id.prompt((notification) => {
// 處理登入失敗
loginFail(notification);
});
}
// 處理登入取得的資訊
function onLogin(response) {
var credential = response.credential,
profile = JSON.parse(decodeURIComponent(encodeURIComponent(window.atob(credential.split(".")[1].replace(/-/g, "+").replace(/_/g, "/"))))),
html = "";
// 儲存登入帳號
localStorage.autoLoginGoogleAccount = profile.email;
html += "ID: " + profile.sub + "<br/>";
html += "會員暱稱: " + profile.name + "<br/>";
html += "會員頭像:" + profile.picture + "<br/>";
html += "會員 email:" + profile.email + "<br/>";
$status.html(html);
}
// 處理登入失敗
function loginFail(notification) {
/*notification.g 數值 → display: 登入中, skipped: 取消登入, dismissed: 登入成功*/
if (notification.g == "skipped") {
// 取消登入時
$status.html("取消登入 Google 帳號,請稍後再試");
}
if (notification.g == "display"&& notification.h == false) {
// 無痕模式無法登入
$status.html("無法登入 Google 帳號,請離開無痕模式或使用 Chrome 瀏覽器登入。");
}
}
// 進行登出
function logout() {
// 刪除自動登入儲存的帳號
localStorage.autoLoginGoogleAccount = "";
// 登出
google.accounts.id.disableAutoSelect();
$status.html("已登出");
}
init();
// 點擊登入
$("#GOOGLE_login").click(function() {
// 進行登入程序
startLogin();
});
// 點擊登出
$("#GOOGLE_logout").click(function() {
// 進行登出
logout();
});
</script>
- 紅色字串請置換為前面「處理 OAuth 憑證」流程取得的「用戶端 ID」
- 程式碼請放在前面「處理 OAuth 憑證」流程設定的網站
更多 Google 相關文章: