Next.js + GoでGoogle SSOを実現する

Next.js + Go でGoogle SSOを実現する(Google編)

3か月前


Google公式を参考に設定していく(少しわかりづらい)

以下ポイントだけ記載

  1. 認証情報で認証情報を作成 -> OAuth 2.0 クライアント IDを作成する
  2. OAuth 2.0 クライアント IDの作成で、承認済みのリダイレクト URIにバックエンドで実装したコールバックAPIを設定する
  3. 本番運用する場合、OAuth 同意画面にて、ロゴとホームページ・プライバシーポリシー・利用規約のURLが必要になるため事前に準備する
  4. リジェクトされた場合はメールに理由が届き、対応したらメールに返信する必要がある

Next.js + Go でGoogle SSOを実現する(バックエンド編)

3か月前


コールバック用のAPIを準備

func (h *GoogleAuthHandler) HandleGoogleCallback(c *gin.Context) { code := c.Query("code") err := c.Query("error") ctx := c.Request.Context() if err != "" { c.Redirect(http.StatusFound, os.Getenv("APP_URL")+"/login") return } googleUser, authError := h.GoogleAuthService.GetGoogleAuthUser(code) if authError != nil { c.Redirect(http.StatusFound, os.Getenv("APP_URL")+"/login") return } // 後継処理を書く }

コールバックで受け取ったcodeをdecodeし、accessTokenを使ってOpenID Connectへリクエストする 受け取ったresponseからuser情報を取得

package google import ( "context" "encoding/json" "net/http" "github.com/mizuko-dev/paput-api/config" "golang.org/x/oauth2" "golang.org/x/oauth2/google" ) type GoogleAuthUser struct { Sub string `json:"sub"` Email string `json:"email"` VerifiedEmail bool `json:"verified_email"` Name string `json:"name"` GivenName string `json:"given_name"` FamilyName string `json:"family_name"` Picture string `json:"picture"` Locale string `json:"locale"` } type GoogleAuthService struct { OAuthConfig *oauth2.Config } func NewGoogleAuthService() GoogleAuthService { config, _ := config.LoadConfig() oauthConfig := &oauth2.Config{ RedirectURL: config.Google.RedirectURL, ClientID: config.Google.ClientID, ClientSecret: config.Google.ClientSecret, Scopes: []string{ "email", "profile", }, Endpoint: google.Endpoint, } return GoogleAuthService{ OAuthConfig: oauthConfig, } } func (r *GoogleAuthService) GetGoogleAuthUser(code string) (*GoogleAuthUser, error) { token, err := r.OAuthConfig.Exchange(context.Background(), code) if err != nil { return nil, err } client := &http.Client{} req, _ := http.NewRequest("GET", "https://openidconnect.googleapis.com/v1/userinfo", nil) req.Header.Set("Authorization", "Bearer "+token.AccessToken) response, err := client.Do(req) if err != nil { return nil, err } defer response.Body.Close() var GoogleAuthUser GoogleAuthUser if err := json.NewDecoder(response.Body).Decode(&GoogleAuthUser); err != nil { return nil, err } return &GoogleAuthUser, nil }

Next.js + Go でGoogle SSOを実現する(フロントエンド編)

3か月前


ボタン押下時のhandler

'use client'; export const handleGoogleSignIn = (): void => { const clientId = process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID; const redirectUri = process.env.NEXT_PUBLIC_GOOGLE_REDIRECT_URI; // Google OAuth 2.0 URLの構築 const scope = 'email profile openid'; const responseType = 'code'; const authUrl = `https://accounts.google.com/o/oauth2/v2/auth?client_id=${clientId}&redirect_uri=${redirectUri}&scope=${scope}&response_type=${responseType}&access_type=offline&prompt=consent`; // ユーザーをGoogleの認証ページへリダイレクト window.location.href = authUrl; };

ボタンのデザイン(ボタンはGoogleのデザイン規約に準拠)

<GoogleSingInButton handler={handleGoogleSignIn} />

ボタンを押下すると、Google側のログイン画面へ遷移する