| name | goth-providers |
| description | This skill should be used when the user asks to "add a provider", "configure google oauth", "set up microsoft login", "azure ad authentication", "oauth provider setup", "add social login", or needs help with specific OAuth provider configuration in Goth. |
Goth Providers
Expert guidance for configuring OAuth providers with github.com/markbates/goth. Focus on Google and Microsoft (Azure AD) with patterns applicable to all 70+ supported providers.
Provider Registration Pattern
Register providers at application startup using goth.UseProviders():
import (
"github.com/markbates/goth"
"github.com/markbates/goth/providers/google"
"github.com/markbates/goth/providers/azureadv2"
)
func init() {
goth.UseProviders(
google.New(
os.Getenv("GOOGLE_CLIENT_ID"),
os.Getenv("GOOGLE_CLIENT_SECRET"),
"http://localhost:3000/auth/google/callback",
"email", "profile",
),
azureadv2.New(
os.Getenv("AZURE_CLIENT_ID"),
os.Getenv("AZURE_CLIENT_SECRET"),
"http://localhost:3000/auth/microsoft/callback",
azureadv2.ProviderOptions{
Tenant: azureadv2.CommonTenant,
Scopes: []string{"openid", "profile", "email"},
},
),
)
}
Provider Constructor Pattern
All providers follow a similar constructor pattern:
provider.New(
clientID string, // OAuth client/application ID
clientSecret string, // OAuth client secret
callbackURL string, // Your callback URL (must match provider config)
scopes ...string, // Permission scopes to request
)
Callback URL Configuration
The callback URL must:
- Match exactly what's registered in the provider's developer console
- Be accessible from the user's browser
- Handle the OAuth callback response
// Development
callbackURL := "http://localhost:3000/auth/google/callback"
// Production
callbackURL := "https://yourdomain.com/auth/google/callback"
// Dynamic based on environment
func getCallbackURL(provider string) string {
baseURL := os.Getenv("BASE_URL")
if baseURL == "" {
baseURL = "http://localhost:3000"
}
return fmt.Sprintf("%s/auth/%s/callback", baseURL, provider)
}
Scopes Reference
Common Scopes
| Scope | Purpose |
|---|---|
openid |
OpenID Connect authentication |
email |
Access user's email address |
profile |
Access basic profile info (name, picture) |
Provider-Specific Scopes
Request only scopes needed for your application. More scopes = more user friction.
Google OAuth Setup
Console Configuration
- Go to Google Cloud Console
- Create project or select existing
- Enable "Google+ API" or "People API"
- Configure OAuth consent screen
- Create OAuth 2.0 credentials (Web application)
- Add authorized redirect URIs
Code Configuration
import "github.com/markbates/goth/providers/google"
google.New(
os.Getenv("GOOGLE_CLIENT_ID"),
os.Getenv("GOOGLE_CLIENT_SECRET"),
"http://localhost:3000/auth/google/callback",
"email", "profile", // Common scopes
)
Google-Specific Scopes
| Scope | Data Access |
|---|---|
email |
Email address |
profile |
Name, picture, locale |
https://www.googleapis.com/auth/calendar.readonly |
Read calendars |
https://www.googleapis.com/auth/drive.readonly |
Read Drive files |
Access User Data
user, _ := gothic.CompleteUserAuth(w, r)
// user.Email - Google email
// user.Name - Display name
// user.AvatarURL - Profile picture
// user.AccessToken - For Google API calls
For detailed Google setup steps, see references/google-oauth-setup.md.
Microsoft (Azure AD) Setup
Azure Portal Configuration
- Go to Azure Portal
- Navigate to Azure Active Directory → App registrations
- Create new registration
- Add redirect URI (Web platform)
- Create client secret under Certificates & secrets
- Configure API permissions
Code Configuration
import "github.com/markbates/goth/providers/azureadv2"
azureadv2.New(
os.Getenv("AZURE_CLIENT_ID"),
os.Getenv("AZURE_CLIENT_SECRET"),
"http://localhost:3000/auth/microsoft/callback",
azureadv2.ProviderOptions{
Tenant: azureadv2.CommonTenant, // or specific tenant ID
Scopes: []string{
"openid",
"profile",
"email",
},
},
)
Tenant Options
// Any Microsoft account (personal + work/school)
Tenant: azureadv2.CommonTenant
// Only work/school accounts
Tenant: azureadv2.OrganizationsTenant
// Only personal Microsoft accounts
Tenant: azureadv2.ConsumersTenant
// Specific organization only
Tenant: "your-tenant-id"
Microsoft-Specific Scopes
| Scope | Data Access |
|---|---|
openid |
ID token |
profile |
Name, preferred_username |
email |
Email address |
User.Read |
Full profile via Graph API |
Calendars.Read |
Read calendar events |
Files.Read |
Read OneDrive files |
Access User Data
user, _ := gothic.CompleteUserAuth(w, r)
// user.Email - Microsoft email
// user.Name - Display name
// user.UserID - Azure AD object ID
// user.AccessToken - For Microsoft Graph API calls
// user.IDToken - JWT with claims
For detailed Microsoft setup steps, see references/microsoft-oauth-setup.md.
Multiple Providers Pattern
Support multiple login options:
func init() {
goth.UseProviders(
google.New(
os.Getenv("GOOGLE_CLIENT_ID"),
os.Getenv("GOOGLE_CLIENT_SECRET"),
getCallbackURL("google"),
"email", "profile",
),
azureadv2.New(
os.Getenv("AZURE_CLIENT_ID"),
os.Getenv("AZURE_CLIENT_SECRET"),
getCallbackURL("microsoft"),
azureadv2.ProviderOptions{
Tenant: azureadv2.CommonTenant,
Scopes: []string{"openid", "profile", "email"},
},
),
)
}
// Login page template
const loginTemplate = `
<h1>Sign In</h1>
<a href="/auth/google">Sign in with Google</a>
<a href="/auth/microsoft">Sign in with Microsoft</a>
`
Provider Selection at Runtime
Get available providers:
// List all registered providers
providers := goth.GetProviders()
for name, provider := range providers {
fmt.Printf("Provider: %s\n", name)
}
// Get specific provider
provider, err := goth.GetProvider("google")
if err != nil {
// Provider not registered
}
Custom Provider Name
Override the provider name if needed:
// In your route handler
gothic.GetProviderName = func(req *http.Request) (string, error) {
// Extract from URL path: /auth/{provider}
parts := strings.Split(req.URL.Path, "/")
if len(parts) >= 3 {
return parts[2], nil
}
return "", errors.New("no provider specified")
}
Environment Variables
Organize credentials by provider:
# Google OAuth
GOOGLE_CLIENT_ID=xxx.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=GOCSPX-xxx
# Microsoft/Azure AD
AZURE_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
AZURE_CLIENT_SECRET=xxx~xxx
AZURE_TENANT_ID=common # or specific tenant
# Application
BASE_URL=http://localhost:3000
SESSION_SECRET=your-32-byte-secret
Common Issues
"redirect_uri_mismatch" Error
The callback URL doesn't match provider configuration:
- Check exact URL including protocol (http vs https)
- Verify trailing slashes match
- Ensure port number is correct
- Check for localhost vs 127.0.0.1 differences
"invalid_client" Error
Client ID or secret is wrong:
- Verify environment variables are loaded
- Check for extra whitespace in credentials
- Ensure correct project/app is selected in console
"access_denied" Error
User denied permission or scopes are invalid:
- Review requested scopes
- Check consent screen configuration
- Verify app is published (if Google)
Quick Reference
| Task | Code |
|---|---|
| Register provider | goth.UseProviders(provider) |
| Get provider | goth.GetProvider("name") |
| List providers | goth.GetProviders() |
| Dynamic callback | fmt.Sprintf("%s/auth/%s/callback", baseURL, provider) |
Related Skills
- goth-fundamentals - Core Goth concepts and interfaces
- goth-echo-security - Framework integration and security
Reference Documentation
references/google-oauth-setup.md- Step-by-step Google configurationreferences/microsoft-oauth-setup.md- Step-by-step Microsoft/Azure AD configuration