iT邦幫忙

2023 iThome 鐵人賽

DAY 15
0

當我們平常像下面這樣透過Google OAuth進行登入時,點選登入後會需要有一個Redirect URI,只要Google驗證通過後,就會重新導向去打該網址,讓自己的後端能接收到使用者登入後的資訊~

https://ithelp.ithome.com.tw/upload/images/20230930/2011599088lDeLhzR3.png

所以我們需要做一個新的Handler,來專門處理OAuth Login後的資訊~

  1. 在router資料夾下先建立oauth.go

    https://ithelp.ithome.com.tw/upload/images/20230930/201159901fFluQiwr0.png

  2. 我們需要import google提供的以下套件

    // oauth.go
    import (	
    	"golang.org/x/oauth2"
    	"golang.org/x/oauth2/google"
    	"google.golang.org/api/drive/v3" //go get google.golang.org/api/drive/v3
    )
    
  3. 寫上用來處理登入後的OAuthLogin,用一樣的方式,接受一個app作為參數,並回傳一個HandlerFunc,這邊先把功能寫在這做測試,之後再移出去。

    // oauth.go
    func OAuthLogin(app *app.Application) gin.HandlerFunc {
    	return func(c *gin.Context) {
            // 從 URL 參數中獲取授權碼
    		authCode := c.Query("code")
            // 建立 OAuth2 Config
    		config := &oauth2.Config{
    			ClientID:     os.Getenv("ClientID"),
    			ClientSecret: os.Getenv("ClientSecret"), // from https://console.developers.google.com/project/<your-project-id>/apiui/credential
    			Endpoint:     google.Endpoint,
    			Scopes:       []string{drive.DriveScope},
    			RedirectURL:  os.Getenv("RedirectURL"),
    		}
            // 交換授權碼以獲取token
    		tok, err := config.Exchange(context.TODO(), authCode)
    		if err != nil {
    			log.Printf("Unable to retrieve token from web %v", err)
    		}
            // 使用token初始化 Google Drive 服務
    		client := config.Client(context.Background(), tok)
    		srv, err := drive.NewService(c, option.WithHTTPClient(client))
    		if err != nil {
    			log.Printf("Unable to retrieve Drive client: %v", err)
    		}
            // 列出 Google Drive 上的文件
    		r, err := srv.Files.List().PageSize(10).
    			Fields("nextPageToken, files(id, name)").Do()
    		if err != nil {
    			log.Printf("Unable to retrieve files: %v", err)
    		}
    		fmt.Println("Files:")
    		if len(r.Files) == 0 {
    			fmt.Println("No files found.")
    		} else {
    			for _, i := range r.Files {
    				fmt.Printf("%s (%s)\n", i.Name, i.Id)
    			}
    		}
            // 將 HTML 寫入回應,顯示授權成功的消息
    		_, err = c.Writer.Write([]byte("<html><title>Login</title> <body> Authorized successfully, please close this window</body></html>"))
    		if err != nil {
    			log.Printf("Unable to write HTML: %v", err)
    		}
    
    	}
    }
    

    我們上面寫了一個簡單的範例,執行以下的動作

    • 從 URL 參數中獲取授權碼 authCode,這是 Google OAuth 登入頁面成功後,重新導向時帶回來的參數。
    • 我們一樣從env讀取參數創建一個 oauth2.Config 實例。
    • 使用 config.Exchange 方法交換授權碼 authCode 來獲取存取令牌 tok
    • 使用取得的存取令牌初始化一個 Google Drive 服務的 drive.Service 實例。
    • 使用 srv.Files.List() 方法列出 Google Drive 上的文件,並列出文件的名稱和 ID。
    • 最後,顯示一個簡單的 HTML ,表達授權成功。
  4. 最後,我們到v1.go註冊寫好的路由~

    func RegisterRouter(router *gin.RouterGroup, app *app.Application) {
    	v1 := router.Group("/v1")
    	{
    		v1.POST("/callback", Callback(app))
    		v1.GET("/ouath-login", OAuthLogin(app))
    	}
    }
    

這樣就完成OAuth Login的部分了,那我們今天就先寫到這,明天見~


上一篇
Day14 Sever"啟動" - Gin + ( Lambda or Ngrok ) 04
下一篇
Day16 GoogleDrive API 02
系列文
Golang LineBot X GoogleDrive:LINE有各種限制!? 那就丟上Drive吧!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言