GitHub
GitHub OAuth 2.0 provider — setup, configuration, scopes, email handling, and calling the sign-in flow.
GitHub
Setup
- Go to GitHub Developer Settings.
- Create an OAuth App.
- Set the authorization callback URL to
{BaseURL}/auth/oauth/github/callback.
Configuration
import "github.com/nazimdjebloun/go-auth/provider/github"
goauth.WithAuthentication(goauth.AuthenticationConfig{EmailPassword: true, OAuth: true}),
goauth.WithProvider(github.New(github.Config{
ClientID: os.Getenv("GITHUB_CLIENT_ID"), // required
ClientSecret: os.Getenv("GITHUB_CLIENT_SECRET"), // required
RedirectURL: "https://myapp.com/auth/oauth/github/callback", // required
Scopes: nil, // optional, default []string{"user:email"}
}))| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
ClientID | string | Required | — | From your GitHub OAuth App. |
ClientSecret | string | Required | — | From your GitHub OAuth App. |
RedirectURL | string | Required | — | Must exactly match the callback URL configured in the GitHub App settings. |
Scopes | []string | Optional | ["user:email"] | Override to request additional GitHub scopes. |
Email handling
The adapter rejects non-2xx profile and email responses and missing or non-positive profile id values. Invalid profiles fail with provider_error; they cannot create, link, or authenticate an identity.
GitHub's /user endpoint only returns an email when the user has set a public profile email. When it's empty, the provider falls back to /user/emails (which needs the user:email scope) and picks the address marked both primary and verified — if none qualifies, the exchange fails rather than silently using an unverified address.
When the public profile email is present, it's treated as verified without a separate check: GitHub only allows a verified address to be set as the public one, so a non-empty user.Email is verified by construction.
The display name falls back to the GitHub username (login) when the account has no display name set.
Frontend client setup
The Client example below calls the same apiRequest(baseUrl, method, path, body) helper used throughout these guides — see Client → Setup.
Signing in
Start the flow — GET /auth/oauth/github
Public. Returns GitHub's authorization URL — PKCE (S256) is always included, whether or not GitHub strictly requires it for this app. Redirect the browser there; GitHub handles the rest until it redirects back to your callback URL.
Response (200 OK): { "url": "https://github.com/login/oauth/authorize?..." }
Errors
| Code | Status | Cause |
|---|---|---|
provider_not_found | 404 | The requested provider is not registered while OAuth routes are mounted |
curl
curl https://api.myapp.com/auth/oauth/githubNo Origin header needed — this is a GET with no state-changing effect, so OriginCheck doesn't apply to it.
OAuth paths are unmounted when AuthenticationConfig.OAuth is false. Enabling it without a provider fails startup. Registration OAuth controls account creation independently.
Programmatic (Go)
flow, err := auth.Services().OAuth.Initiate(ctx, "github")
if err != nil {
// wraps a *domain.AuthError — provider_not_found if the name is wrong
}
// Bind flow.State to the initiating browser as the HTTP handler does,
// then redirect the browser to flow.URL.Client
const { url } = await apiRequest(API_BASE, "GET", "/auth/oauth/github");
window.location.href = url;The callback — GET/POST /auth/oauth/github/callback
Admin accounts stop for email 2FA by default. Handle step=two_factor, challengeId, and expiresAt on the landing URL and finish through POST /auth/2fa/verify before treating the user as logged in. See Callback outcomes.
GitHub redirects here itself — your frontend never calls this URL directly. On completed login it sets session cookies and redirects the browser to {BaseURL}/auth/callback; on failure, to {BaseURL}/auth/callback?error={code}&provider=github. Your frontend route at {BaseURL}/auth/callback reads that query string to know whether to show the app or an error.
See Routes for the full parameter reference, Error Handling for every error this can redirect back with, and Guides → OAuth linking for connecting GitHub to an account that's already logged in (a different flow from the sign-in one above).
Next
- Google — the other built-in provider
- OAuth linking — link/unlink/list connected providers on an existing account
- Authentication — the response shape once a session exists, regardless of how it was created