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.