趣味で開発しているアプリのカレンダー機能を充実させたいと思い、Google Calendar の情報を表示する機能を追加することにしました。
そこで、ユーザーが簡単に Google アカウントと連携できるよう、いつも見るような同意画面で Google Calendar 連携できるようにしたいと思い実装しました。
処理のイメージは以下のような感じです。
Google Calendar を取得するには、Google Cloud で Google Calendar API を有効にしたり、トークンを取得できるように設定する必要があります。
Next.js の API 機能や Node.js での実装例が多くありますが、今回は Go でのバックエンドを選択しました。
以下がその実装例です。
フロントエンドの部分は Google 認証用の URL を生成する API を呼び出すように実装するだけです。(概要※1)
import Link from "next/link"
import { type FC, useEffect } from "react"
export const SettingPage: FC = () => {
const googleOAuthUrl = "http://localhost:8000/v2/auth/google-oauth/request"
return (
<div>
<Link href={googleOAuthUrl}>Google連携</Link>
</div>
)
}
フロント側で Google 連携ボタンがクリックされた時に呼ばれる API は以下のようになります。(概要※2,3)
// 「http://localhost:8000/v2/auth/google-oauth/request」が叩かれた際に呼ばれる関数
func V2GoogleOAuthRequestGetController(ctx *gin.Context) {
config := &oauth2.Config{
// [Google Cloud の設定 | 8. Client ID と Client Secret が表示されるので、それぞれを大切にメモしておく] で取得した値を入れる
ClientID: "12345-hogefuga.apps.googleusercontent.com",
ClientSecret: "HOGE-FUGA",
Endpoint: google.Endpoint,
// アプリとして欲しい権限を指定する
Scopes: []string{
"https://www.googleapis.com/auth/calendar.calendars.readonly",
"https://www.googleapis.com/auth/calendar.calendarlist.readonly",
},
RedirectURL: "http://localhost:8000/v2/auth/google-oauth/callback",
}
// AuthCodeURLの第一引数に入れた値がcallback URLに state として渡されるので、ユーザーを特定できるIDなどを入れる
userID, _ := ctx.Value("userId").(string)
url := config.AuthCodeURL(userID, oauth2.AccessTypeOffline)
ctx.Redirect(http.StatusTemporaryRedirect, url)
}
ユーザが Google の同意画面で同意を行った後にリダイレクトされた時に呼ばれる API は以下のようになります。(概要※5)
// 「http://localhost:8000/v2/auth/google-oauth/callback」が叩かれた際に呼ばれる関数
func V2GoogleOAuthCallbackGetController(ctx *gin.Context) {
// ~/callback?state=userId&code=authCode という形でリダイレクトされるので認証コードを取得
code := ctx.Query("code")
// ~/callback?state=userId&code=authCode 認証URLを作成した際に設定した値を取得
userID, _ := uuid.Parse(c.Query("state"))
config := &oauth2.Config{
ClientID: "12345-hogefuga.apps.googleusercontent.com",
ClientSecret: "HOGE-FUGA",
Endpoint: google.Endpoint,
Scopes: []string{
"https://www.googleapis.com/auth/calendar.calendars.readonly",
"https://www.googleapis.com/auth/calendar.calendarlist.readonly",
},
RedirectURL: "http://localhost:8000/v2/auth/google-oauth/callback",
}
// GoogleからTokenを貰う
oAuth2Token, _ := config.Exchange(ctx, code)
// DBなどにTokenを保存する
save(oAuth2Token, userID)
// 連携完了後に表示したい画面にリダイレクトする
c.Redirect(http.StatusTemporaryRedirect, "http://localhost:3000/setting")
}
ユーザの Google Calendar 情報を取得できるトークンの取得はこれで完了です。
他にもトークンをリフレッシュしたり、トークンを使って Google Calendar の情報を取得する必要があります。
そこらへんの実装はまた別の記事で書きたいと思います。
宣伝: @TTrpbm
Google Cloud Platform(GCP)の OAuth 認証の設定
Google 認証と OAuth2.0 で、Google サービスと連携する例のアレを作る
Golang で Google OAuth でのアカウント連携をする
Twitterフォロー待ってます!