ユーザーアイコン

mizuko

3か月前

0
0

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

Go
Google

コールバック用の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 }