2021年9月20日

Google 帳號資訊如何辨別真偽﹍後端驗證用戶資料與 token 的技巧

Google 帳號資訊如何辨別真偽﹍後端驗證用戶資料與 token 的技巧

Wayne Fu 0 A+
過去曾使用「Google 試算表」來打造及存放會員系統,而會員註冊的部分可利用「FB API 製作登入按鈕」取得帳號資訊。但 FB API 限制較多也不好操作,後來使用「Google API 製作登入按鈕」取得基本資訊,並搭配「People API」取得更多個人資訊。 有第三方 API 處理會員註冊問題真的方便又安心,不用經手棘手的帳號密碼問題,可參考「FB API 製作登入按鈕」的詳細說明。不過久了可能會面臨一種狀況:「被大量惡意註冊怎麼辦?」當提供的服務如果出名、爆紅了,就會有各種原因出現大量註冊,例如用來鑽漏洞、或是被公關公司盯上成為目標。 前端經第三方 API 取得的使用者資訊不會有什麼問題,但傳送到後端的資料就無法保證了,一方面所有中繼傳輸設備都可能被攔截,一方面有心人說不定已寫好了執行腳本,跳過前端直接發送大量的假帳號註冊請求給後端,一次註冊了幾百個帳號也說不定。 依照這樣的攻擊手法,我們有可能在後端辨識出,這幾百個註冊的 Google 帳號是真是假嗎? (圖片出處: pixabay.com)

一、Google API 使用者資訊

首先複習一下「Google API 登入按鈕」,Google 登入後可以取得這些公開資訊:ID暱稱頭像Email。接著儲存到資料庫後,要拿 ID 或 Email 做為單一不重複的帳號依據都可。 然而前端傳送到後端的註冊請求,資訊想造假並不困難,"暱稱"、"頭像"、"Email" 就不用說了,如果 "ID" 資訊是假的,後端有辦法判斷嗎?畢竟 ID 是第三方 API 產生的,我們不會知道運算邏輯,所以哪知道這字串是真是假~ 好消息是,實際上別說 "ID",我們連 "暱稱"、"頭像"、"Email" 全部的資訊都有辦法辨別真偽!趕快來看看是怎麼回事。

二、後端進行身份驗證

根據 Google 官網文件「使用後端服務器進行身份驗證」,官方明確告知我們要如何對使用者進行身份驗證:
如果您將Google登錄用於與後端服務器通信的應用或網站,則可能需要識別服務器上當前登錄的用戶。為了安全地執行此操作,請在用戶成功登錄後,使用HTTPS將用戶的ID令牌發送到您的服務器。然後,在服務器上,驗證ID令牌的完整性,並使用令牌中包含的用戶信息建立會話或創建新帳戶
意思就是說,使用者在前端登入 Google 帳號後取得的資訊,其中包含了 "ID令牌",也就是 ID token,必須傳到後端伺服器進行驗證。驗證無誤後,再將 ID token 中包含的使用者資訊(這才是不會被竄改的資訊)進行註冊之用。 根據官網說明,驗證 ID token 的網址如下: https://oauth2.googleapis.com/tokeninfo?id_token=這裡是 ID token 字串 如果 id_token 驗證無誤,就會傳回使用者資訊,此時可以跟前端接收到的使用者資訊一一比對,就能驗證 Google 帳號的註冊資料真假了。官網也提供該網址回傳的資料範例,大概長這樣: { "iss": "https://accounts.google.com", "sub": "110169484474386276334", "azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com", "aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com", "iat": "1433978353", "exp": "1433981953", "email": "testuser@gmail.com", "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"} 主要看看 name、email、picture(頭像網址) 這幾項是否吻合就可以了。

三、取得 id token 範例程式碼

修改一下「Google API 登入按鈕」的範例程式碼,就可取得 id_token、access_token 等資訊: <script src="https://apis.google.com/js/platform.js" async="async"></script> <meta name="google-signin-client_id" content="5432xxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com"/> <div class="g-signin2" data-onsuccess="onSignIn"></div> 目前狀態: <span id="GOOGLE_STATUS_1"></span> <script> // 登入之後 function onSignIn(googleUser) { var profile = googleUser.getBasicProfile(), target = document.getElementById("GOOGLE_STATUS_1"), html = ""; html += "ID: " + profile.getId() + "<br/>"; html += "會員暱稱: " + profile.getName() + "<br/>"; html += "會員頭像:" + profile.getImageUrl() + "<br/>"; html += "會員 email:" + profile.getEmail() + "<br/>"; html += "id token:" + googleUser.getAuthResponse().id_token + "<br/>"; html += "access token:" + googleUser.getAuthResponse(true).access_token + "<br/>"; target.innerHTML = html; } </script>
  • 紅色字串改為自己的「用戶端 ID」,請參考前一篇所有流程注意事項

四、驗證 id token

下面是以上範例程式碼「官方 Google 登入按鈕」的效果,執行登入可取得各項資料:
目前狀態: 如前面「二、後端進行身份驗證」的說明,以下紅字改為自己的 id token 字串即可取得驗證結果: https://oauth2.googleapis.com/tokeninfo?id_token=這裡是 ID token 字串

五、驗證 access token

前面的範例程式碼附帶提供了 access token 資訊,取得的方式請參考討論串「How to properly get Access Token from logged in Google Sign In」。 這裡額外說明如何驗證 access token 真偽。此討論串「How can I verify a Google authentication API access token?」提到 Google 兩個版本的驗證網址: https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=這裡是 access token 字串 https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=這裡是 access token 字串 任選一個將紅字改為自己的 access token 字串即可取得驗證結果。
更多「資訊安全」相關文章:
0 0
如這篇文章對你有幫助,歡迎「分享」到 FB、「追蹤」粉絲團、「訂閱」最新文章

沒有留言:

張貼留言注意事項:

◎ 勾選「通知我」可收到後續回覆的mail!
◎ 請在相關文章留言,與文章無關的主題可至「Blogger 社團」提問。
◎ 請避免使用 Safari 瀏覽器,否則無法登入 Google 帳號留言(只能匿名留言)!
◎ 提問若無法提供足夠的資訊供判斷,可能會被無視。建議先參考這篇「Blogger 提問技巧及注意事項」。
◎ CSS 相關問題非免費諮詢,建議使用「Chrome 開發人員工具」尋找答案。
◎ 手機版相關問題請參考「Blogger 行動版範本的特質」→「三、行動版範本不一定能執行網頁版工具」;或參考「Blogger 行動版範本修改技巧 」,或本站 Blogger 行動版標籤相關文章。
◎ 非官方範本問題、或貴站為商業網站,請參考「Blogger 免費諮詢 + 付費諮詢
◎ 若是使用官方 RWD 範本,請參考「Blogger 推出全新自適應 RWD 官方範本及佈景主題」→ 不建議對範本進行修改!
◎ 若留言要輸入語法,"<"、">"這兩個符號請用其他符號代替,否則語法會消失!
◎ 為了過濾垃圾留言,所有留言不會即時發佈,請稍待片刻。
◎ 本站「已關閉自刪留言功能」。

TOP