Skip to content

yuen-quinn/authx

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

10 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

authx

A simple and flexible authentication library for Dart applications supporting multiple OAuth providers with type-safe provider management.

Features

  • πŸ” OAuth 2.0 authentication
  • 🌐 Multiple provider support (GitHub, Google)
  • πŸ“¦ Easy integration with singleton pattern
  • 🎯 Type-safe API with Provider enum
  • πŸ”„ State management with configurable expiration
  • πŸ›‘οΈ Built-in error handling and validation

Supported Providers

  • GitHub - Complete OAuth flow with user profile and email
  • Google - OpenID Connect with profile information

Installation

Add this to your pubspec.yaml:

dependencies:
  authx: ^1.0.2

Then run:

dart pub get

Quick Start

import 'package:authx/authx.dart';

void main() async {
  // 1. Configure AuthX singleton with providers (call once)
  AuthX.configure(
    expiration: Duration(minutes: 30),
    providers: {
      'github': GitHubProvider(
        clientId: 'your_github_client_id',
        clientSecret: 'your_github_client_secret',
        redirectUri: 'http://localhost:8080/api/v1/auth/github/callback',
      ),
      'google': GoogleProvider(
        clientId: 'your_google_client_id',
        clientSecret: 'your_google_client_secret',
        redirectUri: 'http://localhost:8080/api/v1/auth/google/callback',
      ),
    },
  );

  // 2. Get the singleton instance
  final authX = AuthX.instance;

  // 3. Get authorization URL (redirect user to this URL)
  final authUrl = authX.getAuthorizationUrl(Provider.github);
  print('Redirect user to: $authUrl');

  // 4. Handle callback and get user profile
  try {
    final profile = await authX.handleCallback(
      providerId: Provider.github,
      query: {
        'code': 'authorization_code_from_callback',
        'state': 'state_from_auth_url',
      },
    );

    print('βœ“ Authentication successful!');
    print('User email: ${profile.email}');
    print('User name: ${profile.name}');
    print('Avatar: ${profile.avatar}');
    print('Provider: ${profile.provider}');
  } on DartAuthException catch (e) {
    print('βœ— Authentication failed: ${e.message}');
    print('Error code: ${e.code}');
  }
}

API Reference

Provider Enum

Type-safe provider identification:

enum Provider {
  github,
  google;
  
  String get value; // Returns string representation
  static Provider fromString(String value); // Convert string to enum
}

AuthX Class

Main authentication manager with singleton pattern.

Configuration

AuthX.configure({
  Duration? expiration, // State expiration time (default: 5 minutes)
  Map<String, OAuthProvider>? providers, // Provider configuration
});

Methods

  • AuthX.instance - Get singleton instance
  • getAuthorizationUrl(Provider providerId) - Generate auth URL with state
  • handleCallback({Provider providerId, Map<String, String> query}) - Process callback
  • registerProvider(Provider id, OAuthProvider provider) - Register additional provider
  • isStateValid(String state) - Validate state without consuming it
  • cleanStates() - Remove expired states

OAuthProfile

User profile returned after successful authentication:

class OAuthProfile {
  final String providerId;          // Provider ID as string
  final String email;               // User email (always present)
  final String? name;               // User display name
  final String? avatar;             // Profile avatar URL
  final String? provider;           // Provider name as string
  final Map<String, dynamic> raw;   // Raw provider response
}

Error Handling

Built-in exception types for comprehensive error handling:

try {
  final profile = await authX.handleCallback(...);
} on DartAuthException catch (e) {
  print('Error: ${e.message}');
  print('Code: ${e.code}');
  
  // Common error codes:
  // - NOT_CONFIGURED: AuthX not configured
  // - ALREADY_CONFIGURED: AuthX already configured
  // - INVALID_CALLBACK_PARAMS: Missing code or state
  // - INVALID_OR_EXPIRED_STATE: State invalid or expired
  // - PROVIDER_NOT_FOUND: Provider not registered
  // - TOKEN_EXCHANGE_FAILED: OAuth token exchange failed
  // - PROFILE_FETCH_FAILED: Failed to fetch user profile
  // - MISSING_EMAIL: Email not available in profile
}

Provider Configuration

GitHub Provider

GitHubProvider(
  clientId: 'your_client_id',
  clientSecret: 'your_client_secret',
  redirectUri: 'http://localhost:8080/api/v1/auth/github/callback',
)

Required OAuth App Settings:

  • Authorization callback URL: http://localhost:8080/api/v1/auth/github/callback
  • Scopes requested: user:email

Google Provider

GoogleProvider(
  clientId: 'your_client_id',
  clientSecret: 'your_client_secret',
  redirectUri: 'http://localhost:8080/api/v1/auth/google/callback',
)

Required OAuth App Settings:

  • Authorized redirect URI: http://localhost:8080/api/v1/auth/google/callback
  • Scopes requested: openid email profile

Advanced Usage

Custom State Management

// Configure custom expiration
AuthX.configure(
  expiration: Duration(hours: 1), // Longer state validity
  providers: providers,
);

// Validate state without consuming
if (authX.isStateValid(state)) {
  // State is valid
}

// Clean up expired states
authX.cleanStates();

Multiple Provider Registration

final authX = AuthX.instance;

// Register additional providers after configuration
authX.registerProvider(
  Provider.github,
  GitHubProvider(/* config */),
);

authX.registerProvider(
  Provider.google,
  GoogleProvider(/* config */),
);

Testing

For testing purposes, you can reset the AuthX configuration:

// Reset singleton (for testing only)
AuthX.reset();

Examples

See the example directory for complete working examples:

Security Considerations

  • State Management: States automatically expire to prevent replay attacks
  • Secret Management: Never commit client secrets to version control
  • Redirect URIs: Ensure redirect URIs match your OAuth app configuration
  • HTTPS: Always use HTTPS in production environments
  • State Validation: Always validate the state parameter in callbacks

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure all tests pass
  5. Submit a pull request

License

MIT License - see the LICENSE file for details.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages