GitHub Sign In
A comprehensive Flutter package for GitHub OAuth authentication with automatic user data fetching. Supports both mobile and web platforms with a clean, easy-to-use API.
β¨ Features
- π Complete OAuth Flow: Handles the entire GitHub OAuth authentication process
- π€ User Data Fetching: Automatically retrieves user profile information and verified email
- π± Cross-Platform: Works on iOS, Android, and Web
- π¨ Customizable UI: Configurable sign-in page with custom titles and styling
- π Secure: Follows OAuth 2.0 best practices
- π Rich User Info: Access to profile data, repositories, followers, and more
- β‘ Easy Integration: Simple API with comprehensive error handling
π Requirements
- Flutter 3.35.7+
- Dart 3.9.2+
π Installation
Add this to your package's pubspec.yaml file:
dependencies:
github_oauth_signin: ^1.0.6
Then run:
flutter pub get
π§ Setup
1. Create a GitHub OAuth App
- Go to GitHub Developer Settings
- Click "New OAuth App"
- Fill in your application details:
- Application name: Your app name
- Homepage URL: Your app's homepage
- Authorization callback URL: Your redirect URL (e.g.,
https://yourapp.com/auth/callback)
- Note down your
Client IDandClient Secret
2. Choose a Redirect URL
This package uses a WebView on mobile and a browser redirect on web, so no extra iOS/Android native configuration is required when you use a normal HTTP/HTTPS redirectUrl.
For local testing, a common choice is:
redirectUrl: http://localhost/callback
GitHub will redirect to that URL with ?code=..., and the package will capture the code from the redirect URL.
π Usage
Basic Implementation
import 'package:flutter/material.dart';
import 'package:github_oauth_signin/github_oauth_signin.dart';
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: GitHubSignInDemo(),
);
}
}
class GitHubSignInDemo extends StatefulWidget {
@override
_GitHubSignInDemoState createState() => _GitHubSignInDemoState();
}
class _GitHubSignInDemoState extends State<GitHubSignInDemo> {
final GitHubSignIn gitHubSignIn = GitHubSignIn(
clientId: 'your-github-client-id',
clientSecret: 'your-github-client-secret',
redirectUrl: 'https://yourapp.com/auth/callback',
);
void _signInWithGitHub() async {
final result = await gitHubSignIn.signIn(context);
switch (result.status) {
case GitHubSignInResultStatus.ok:
print('β
Sign in successful!');
print('π Access Token: ${result.token}');
if (result.userData != null) {
final user = result.userData!;
print('π€ User: ${user['name']} (@${user['login']})');
print('π§ Email: ${user['email']}');
print('π’ Company: ${user['company']}');
print('π Location: ${user['location']}');
print('π Public Repos: ${user['public_repos']}');
print('π₯ Followers: ${user['followers']}');
}
break;
case GitHubSignInResultStatus.cancelled:
print('β Sign in cancelled');
break;
case GitHubSignInResultStatus.failed:
print('β Sign in failed: ${result.errorMessage}');
break;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('GitHub Sign In Demo')),
body: Center(
child: ElevatedButton(
onPressed: _signInWithGitHub,
child: Text('Sign in with GitHub'),
),
),
);
}
}
Advanced Configuration
final GitHubSignIn gitHubSignIn = GitHubSignIn(
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
redirectUrl: 'https://yourapp.com/callback',
scope: 'user,repo,gist', // Custom scopes
title: 'Connect to GitHub', // Custom page title
centerTitle: true, // Center the title
allowSignUp: true, // Allow new user registration
clearCache: true, // Clear browser cache
userAgent: 'MyApp/1.0', // Custom user agent
);
Custom Sign-In Page
final result = await gitHubSignIn.signIn(
context,
appBar: AppBar(
title: Text('Custom GitHub Sign In'),
backgroundColor: Colors.black,
foregroundColor: Colors.white,
),
);
π Available User Data
After successful authentication, the userData field contains:
| Field | Type | Description |
|---|---|---|
login |
String | GitHub username |
id |
int | User ID |
name |
String | Display name |
email |
String | Primary verified email |
avatar_url |
String | Profile picture URL |
bio |
String | User biography |
company |
String | Company name |
location |
String | User location |
blog |
String | Website/blog URL |
public_repos |
int | Number of public repositories |
public_gists |
int | Number of public gists |
followers |
int | Number of followers |
following |
int | Number of users following |
created_at |
String | Account creation date |
updated_at |
String | Last profile update |
π Scopes
Configure the required permissions by setting the scope parameter:
user- Read user profile datauser:email- Read user email addressesrepo- Access repositoriesgist- Access gistsread:org- Read organization membership
Example:
GitHubSignIn(
// ... other parameters
scope: 'user,user:email,repo',
)
π¨ Customization
Sign-In Page Customization
GitHubSignIn(
// ... other parameters
title: 'Connect Your GitHub Account',
centerTitle: false,
allowSignUp: true,
clearCache: true,
userAgent: 'MyApp/1.0.0',
)
Custom AppBar
await gitHubSignIn.signIn(
context,
appBar: AppBar(
title: Text('GitHub Authentication'),
backgroundColor: Color(0xFF24292e), // GitHub dark color
elevation: 0,
),
);
π Error Handling
The package provides comprehensive error handling:
final result = await gitHubSignIn.signIn(context);
switch (result.status) {
case GitHubSignInResultStatus.ok:
// Handle successful sign-in
if (result.userData == null) {
// Token obtained but user data fetch failed
print('Warning: Could not fetch user data');
}
break;
case GitHubSignInResultStatus.cancelled:
// User cancelled the sign-in process
showSnackBar('Sign-in cancelled');
break;
case GitHubSignInResultStatus.failed:
// Sign-in failed with error
showErrorDialog('Sign-in failed: ${result.errorMessage}');
break;
}
π Web Support
On Flutter Web, the OAuth flow works via full-page redirect:
- First, call
signIn()to redirect the browser to GitHub. - After GitHub redirects back to your
redirectUrl(your web app URL), callsignIn()again (for example during app startup) to complete the token exchange using thecodein the URL.
Tip: You can detect the redirect like this:
final bool hasCode = Uri.base.queryParameters['code']?.isNotEmpty == true;
π§ͺ Testing
Run the example app to test the integration:
cd example
flutter run
π Example
Check out the example directory for a complete implementation showing:
- Basic sign-in flow
- User data display
- Error handling
- Custom UI elements
π€ Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
π License
This project is licensed under the MIT License - see the LICENSE file for details.
π Issues
If you encounter any issues, please file them on the GitHub Issues page.
π Additional Resources
Libraries
- github_oauth_signin
- A comprehensive Flutter package for GitHub OAuth authentication.