Docs/Data & Authentication/OAuth2 PKCE

OAuth2 Social Login & PKCE

Zero-dependency OAuth2 social login supporting Google and GitHub with RFC 7636 PKCE protection.

pkg/auth/oauthis a zero-dependency social authentication library for Go. It features built-in support for Google and GitHub, strict RFC 7636 PKCE (S256 code challenge) protection, and timing-safe state validation viasubtle.ConstantTimeCompare.

Why PKCE Matters

Proof Key for Code Exchange (PKCE) eliminates authorization code interception attacks. Even if an attacker intercepts the authorization code redirect, they cannot exchange it for access tokens without the cryptographic ephemeral verifier stored in a secure HttpOnly cookie.

Implementation Example

services/oauth_service.go
go
package auth

import (
	"net/http"
	"os"
	"github.com/misbakhul29/goks/pkg/auth/oauth"
	"github.com/misbakhul29/goks/pkg/router"
)

var GoogleProvider = oauth.NewGoogleProvider(oauth.Config{
	ClientID:     os.Getenv("GOOGLE_CLIENT_ID"),
	ClientSecret: os.Getenv("GOOGLE_CLIENT_SECRET"),
	RedirectURI:  "http://localhost:3000/auth/google/callback",
	Scopes:       []string{"openid", "email", "profile"},
	UsePKCE:      true,
})

func LoginHandler(c *router.Context) error {
	authURL, state, verifier, err := GoogleProvider.AuthCodeURL()
	if err != nil {
		return c.String(http.StatusInternalServerError, err.Error())
	}

	c.SetCookie("oauth_state", state, 300, "/", "", false, true)
	c.SetCookie("oauth_verifier", verifier, 300, "/", "", false, true)

	return c.Redirect(authURL, http.StatusTemporaryRedirect)
}

func CallbackHandler(c *router.Context) error {
	code := c.Query("code")
	state := c.Query("state")
	savedState, _ := c.Cookie("oauth_state")
	verifier, _ := c.Cookie("oauth_verifier")

	if !oauth.ValidateState(savedState, state) {
		return c.String(http.StatusBadRequest, "invalid oauth state")
	}

	profile, err := GoogleProvider.ExchangeAndGetProfile(c.Request().Context(), code, verifier)
	if err != nil {
		return c.String(http.StatusUnauthorized, "token exchange failed")
	}

	return c.JSON(http.StatusOK, profile)
}

Unified User Profile

Providers normalize diverse upstream identity structures into a clean, uniformoauth.UserProfilestruct:

  • ID: Provider-specific unique subject identifier.
  • Email: User's verified primary email.
  • Name: Display name.
  • AvatarURL: Profile picture URL.
  • Provider: Provider name ("google" or "github").
Powered byGoKS WASM16 topics