iT邦幫忙

2023 iThome 鐵人賽

DAY 22
0
SideProject30

Golang LineBot X GoogleDrive:LINE有各種限制!? 那就丟上Drive吧!系列 第 22

Day22 繞過 Google OAuth 在 User Agent 上的使用限制

  • 分享至 

  • xImage
  •  

這幾天我們都是透過電腦版的Line來做測試,但是如果是使用手機版的話,會發現當我們點擊Google OAuth的URL要進行認證授權的時候,雖然前面的步驟都一切正常,但是最後會出現像下面這樣的錯誤。

https://ithelp.ithome.com.tw/upload/images/20231007/20115990VIPpXwByWK.png

這個時候如果我們把網址複製到外面,用手機的Chrome來打開就可以正常的授權登入why?

其實Google OAuth 服務有一個安全政策,限制了在一些特定的瀏覽器或瀏覽器類型中使用 OAuth 進行授權。這裡我們看到的錯誤代碼 403 中的 "disallowed_useragent" ,表示我們使用的是不被 Google 允許的使用者代理 (User Agent)。

透過Line內部打開的瀏覽器,我們稱為In-App browser,也就是說在Line的 In-App browser中,使用了某種特定的 User Agent,而這個 User Agent 又被Google判定為不符合其安全標準,因此導致無法正常授權。

那我們到底是使用什麼User Agent呢? 我們可以透過寫js用navigator.userAgent來撈,但這邊我們直接用這個網站來查詢,以下是我在不同瀏覽器開啟的結果。

  • 電腦Chrome:
    https://ithelp.ithome.com.tw/upload/images/20231007/20115990SBDffxzkY0.png

  • 手機Chrome:
    https://ithelp.ithome.com.tw/upload/images/20231007/20115990z1XsXBEY6Z.jpg

  • Line In-App browser:
    https://ithelp.ithome.com.tw/upload/images/20231007/20115990jOAdi3y3jm.jpg

現在我們可以看出來,Line In-App browser應該就是因為多了Line的字段,所以不被Google允許直接被403擋下來。

不過還好外部瀏覽器是沒問題的,我們只要繞過In-App browser讓使用者到外部去進行授權就好,而好在Line官方本身就有提供一個功能,只要在網址後面加上?openExternalBrowser=1,在點擊網址的時候就會跳轉到外部瀏覽器開啟了。

那我們就來改造一下我們的LoginURL,我們的這個service會需要一個function來幫網址加上?openExternalBrowser=1。首先我們到domain新增drive/login.go,來對service提供功能使用。

// internal\domain\drive\login.go
package drive

import "net/url"

func AppendOpenExternalBrowserParam(originalURL string) (string, error) {
	// 將提供的原始URL字串解析成*url.URL
	parsedURL, err := url.Parse(originalURL)
	if err != nil {
		return "", err
	}
	// 取得URL的查詢參數
	query := parsedURL.Query()
	// 將 "openExternalBrowser" 參數添加到查詢參數中,值為 "1"
	query.Add("openExternalBrowser", "1")
	// 將更新後的查詢參數重新設置到parsedURL中
	parsedURL.RawQuery = query.Encode()
	// 返回修改後的URL
	return parsedURL.String(), nil
}

接著回到login_service.go,我們import剛剛建立的domain drive pkg近來,命名為domainDrive。我們這個service從adapter拿到的oauthURL後丟到domain去取得最終resURL後返回。

// internal\app\service\drive\login_service.go
import (
	"context"
	"log"

	"github.com/onepiece010938/Line2GoogleDriveBot/internal/adapter/dynamodb"
	domainDrive "github.com/onepiece010938/Line2GoogleDriveBot/internal/domain/drive"
)

func (dr *GoogleDriveService) LoginURL(ctx context.Context, lineID string) string {
	oauthURL := dr.driveServiceGoogleOA.OAuthLoginURL(lineID)
	resURL, err := domainDrive.AppendOpenExternalBrowserParam(oauthURL)
	if err != nil {
		log.Println("Error:", err)
		return ""
	}
	return resURL
}

最後我們回到linebot上測試

https://ithelp.ithome.com.tw/upload/images/20231007/20115990QGO3nhM10I.png

可以看到回傳的URL已經有加上對應的參數了,手機版點擊後也能自動跳轉到外部瀏覽器了,那我們今天就寫到這,不知不覺22天了,那我們明天見囉~


上一篇
Day21 Drive Service - 取出OAuth Token操作Drive
下一篇
Day23 Drive Service - 撈出”我的雲端硬碟”&”與我共用”下的資料夾
系列文
Golang LineBot X GoogleDrive:LINE有各種限制!? 那就丟上Drive吧!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
MissterHao
iT邦新手 5 級 ‧ 2023-10-08 00:52:58

Google Ban Ban 我!

/images/emoticon/emoticon40.gif

我要留言

立即登入留言