GitHub Provider
GitHubOAuth2Provider is a prebuilt OAuth2Provider subclass for GitHub OAuth Apps. GitHub does not support PKCE, so a clientSecret is required. For production mobile apps where embedding a secret is a concern, use ProxyOAuthProvider instead.
Package: authyra_flutter
Constructor
GitHubOAuth2Provider({
required String clientId,
required String clientSecret,
String redirectUri = 'authyra://callback',
List<String> scopes = const ['user', 'user:email'],
})
| Parameter | Default | Description |
|---|---|---|
clientId | required | OAuth App client ID from GitHub Developer Settings |
clientSecret | required | OAuth App client secret — GitHub requires this because PKCE is not supported |
redirectUri | 'authyra://callback' | Must exactly match the Authorization callback URL in GitHub settings |
scopes | ['user', 'user:email'] | GitHub OAuth scopes to request |
The provider ID is 'github'.
Setup
1. Create a GitHub OAuth App
Go to GitHub Developer Settings → OAuth Apps → New OAuth App:
- Application name: your app name
- Homepage URL: your website
- Authorization callback URL:
authyra://callback(or your custom scheme)
Note the Client ID and Client secret.
2. Add the provider
import 'package:app_links/app_links.dart';
import 'package:authyra_flutter/authyra_flutter.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
final githubProvider = GitHubOAuth2Provider(
clientId: 'YOUR_GITHUB_CLIENT_ID',
clientSecret: 'YOUR_GITHUB_CLIENT_SECRET',
redirectUri: 'authyra://callback',
);
// Register before Authyra.initialize
OAuth2CallbackHandler.registerProvider('authyra', githubProvider);
AppLinks().uriLinkStream.listen(OAuth2CallbackHandler.handleCallback);
await Authyra.initialize(
client: AuthyraClient(
providers: [githubProvider],
storage: SecureAuthStorage(),
),
);
runApp(const MyApp());
}
3. Platform deep-link config
Android — android/app/src/main/AndroidManifest.xml:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="authyra" />
</intent-filter>
iOS — ios/Runner/Info.plist:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>authyra</string>
</array>
</dict>
</array>
Sign in
try {
final user = await Authyra.instance.signIn('github');
print('Signed in as ${user.name}');
} on AuthenticationCancelledException {
// User closed the browser
} on AuthenticationFailedException catch (e) {
print('GitHub sign-in failed: $e');
}
User fields
AuthUser field | GitHub field | Notes |
|---|---|---|
id | id (int → String) | Stable numeric user ID converted to String |
email | email | May be null if the user's email is private |
name | name or login | Falls back to username if display name is unset |
avatarUrl | avatar_url | |
metadata['login'] | login | GitHub username |
metadata['bio'] | bio | |
metadata['company'] | company | |
metadata['location'] | location | |
metadata['blog'] | blog | |
metadata['twitter_username'] | twitter_username | |
metadata['public_repos'] | public_repos | |
metadata['followers'] | followers | |
metadata['following'] | following |
Scopes
Default scopes: ['user', 'user:email']. Add repository or organization access as needed:
GitHubOAuth2Provider(
clientId: 'YOUR_CLIENT_ID',
clientSecret: 'YOUR_CLIENT_SECRET',
scopes: ['user', 'user:email', 'repo', 'read:org'],
)
See the full list at GitHub OAuth scopes.
Token refresh
GitHub access tokens are long-lived and do not expire by default. GitHubOAuth2Provider sets supportsRefresh: false.
If you enable expiring tokens in your GitHub App settings, implement a custom AuthProvider that calls GitHub's token refresh endpoint and returns an AuthTokenResult.
Private email
If a user's email is set to private on GitHub, the /user API returns null for email. To reliably get the user's primary email, add the user:email scope (included in defaults) and call the /user/emails endpoint separately.
Troubleshooting
"redirect_uri_mismatch" from GitHub
The redirectUri in GitHubOAuth2Provider must match exactly what is set in GitHub Developer Settings → Authorization callback URL.
email is null after sign-in
The user has set their email to private. Add user:email to scopes (it is included by default) but also call GitHub's /user/emails API to get the verified primary email.
Callback never arrives on iOS
Verify the CFBundleURLSchemes entry in Info.plist matches the scheme in your redirectUri (the part before ://).
See also
- ProxyOAuthProvider → — keep the client secret server-side (recommended for production mobile)
- OAuth2Provider → — base class and custom providers
- Flutter Setup → — deep-link wiring