super_better_auth 1.0.2
super_better_auth: ^1.0.2 copied to clipboard
A Dart/Flutter client for the Better Auth platform, enabling secure sign-in, sign-up, and session management in Flutter applications.
Super Better Auth ๐ #
A comprehensive Dart/Flutter client for Better Auth that provides seamless authentication, organization management, and advanced session handling features for your Flutter applications.
๐ Why Super Better Auth? #
- Complete Better Auth Integration - Full support for all Better Auth features
- Organization Management - Built-in team and organization handling
- Advanced Cookie Management - Direct access to authentication cookies
- Type-Safe API - Generated models with JSON serialization
- Flutter-First - Designed specifically for Flutter applications
- Production Ready - Comprehensive error handling and validation
Getting Started #
Add super_better_auth to your project dependencies:
flutter pub add super_better_auth
Or manually add it to your pubspec.yaml:
dependencies:
super_better_auth: <latest_version>
โจ Features #
๐ Authentication #
- โ Email Authentication - Sign in/up with email and password
- โ Social Authentication - GitHub, Google, Discord, and more
- โ Phone Authentication - SMS-based authentication
- โ Username Authentication - Traditional username/password
- โ Anonymous Authentication - Guest user support
- โ Email OTP - One-time password via email
- ๐ Two-Factor Authentication - Enhanced security (coming soon)
๐ข Organization Management #
- โ Organization CRUD - Create, read, update, delete organizations
- โ Member Management - Add, remove, and manage organization members
- โ Team Management - Create and manage teams within organizations
- โ Invitation System - Invite users to join organizations
- โ Role-Based Access - Flexible permission system
- โ Membership Queries - List and filter organization memberships
๐ช Advanced Session Management #
- โ Session Management - Get, validate, and refresh user sessions
- โ Cookie Access - Direct access to authentication cookies
- โ Token Management - JWT token handling and validation
- โ Admin Operations - Administrative user management
๐ง Developer Experience #
- โ Type-Safe API - Generated models with JSON serialization
- โ Error Handling - Comprehensive error types and messages
- โ Flutter Integration - Provider pattern with BetterAuthConsumer
- โ Hot Reload Support - Development-friendly architecture
Usage #
Import the package in your main.dart:
import 'package:flutter/material.dart';
import 'package:super_better_auth/super_better_auth.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await SuperBetterAuth.initialize(url: 'api_url');
runApp(const MyApp());
}
Wrap your MaterialApp with BetterAuthProvider:
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return BetterAuthProvider(
child: MaterialApp(
title: 'BetterAuth',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: const MyHomePage(title: 'Better Auth'),
),
);
}
}
Access BetterAuth client using BetterAuthConsumer:
BetterAuthConsumer(
builder: (context, client) {
return Widget();
}
)
Or directly via:
final client = SuperBetterAuth.client;
๐ Plugin System #
Super Better Auth supports all Better Auth plugins through a modular architecture:
Available Plugins #
import 'package:super_better_auth/plugins/admin/admin_plugin.dart';
import 'package:super_better_auth/plugins/phone/phone_plugin.dart';
import 'package:super_better_auth/plugins/email_otp/email_otp_plugin.dart';
import 'package:super_better_auth/plugins/jwt/jwt_plugin.dart';
import 'package:super_better_auth/plugins/organization/organization_plugin.dart';
Plugin Usage #
final client = SuperBetterAuth.client;
// Core authentication
await client.signIn.email(email: "user@example.com", password: "password");
await client.signUp.social(provider: "github");
// Plugin-specific features
await client.phone.sendOtp(phoneNumber: "+1234567890");
await client.admin.createUser(email: "admin@example.com");
await client.emailOtp.sendOtp(email: "user@example.com");
await client.jwt.getTokens();
// Organization management
await client.organization.createOrganization(name: "My Company");
await client.organization.inviteMember(
organizationId: "org_123",
email: "member@example.com",
role: "member"
);
// Cookie management
final sessionCookie = await client.getCookie('better-auth.session_token');
final allCookies = await client.getCookies();
๐ Advanced Usage Examples #
Organization Management #
final client = SuperBetterAuth.client;
// Create an organization
final createResult = await client.organization.createOrganization(
name: "Acme Corp",
slug: "acme-corp",
logo: "https://example.com/logo.png"
);
if (createResult.isSuccess) {
final organization = createResult.data!;
print("Created organization: ${organization.name}");
// Invite a member
await client.organization.inviteMember(
organizationId: organization.id,
email: "john@example.com",
role: "member"
);
// Create a team
await client.organization.createTeam(
organizationId: organization.id,
name: "Development Team",
description: "Core development team"
);
// List all members
final membersResult = await client.organization.listMembers(organization.id);
if (membersResult.isSuccess) {
for (final member in membersResult.data!) {
print("Member: ${member.user.name} (${member.role})");
}
}
}
Cookie Management #
// Get specific authentication cookies
final sessionToken = await client.getCookie('better-auth.session_token');
final csrfToken = await client.getCookie('better-auth.csrf_token');
// Get all Better Auth cookies
final authCookies = await client.getAuthCookies();
print("Found ${authCookies.length} auth cookies");
// Check if session exists
final hasSession = await client.hasCookie('better-auth.session_token');
if (hasSession) {
print("User is authenticated");
}
// Clear all cookies (sign out completely)
await client.clearCookies();
Using Cookies for Authenticated API Calls #
The SuperBetterAuth client automatically handles cookies for all API calls. However, you can also manually use the retrieved cookies for custom API requests:
import 'package:dio/dio.dart';
// Get the session token cookie
final sessionCookie = await client.getCookie('better-auth.session_token');
if (sessionCookie != null) {
// Create a Dio instance for custom API calls
final dio = Dio();
// Add the session cookie to your custom requests
dio.options.headers['Cookie'] = '${sessionCookie.name}=${sessionCookie.value}';
// Make authenticated API calls to your backend
final response = await dio.get('https://your-api.com/protected-endpoint');
// Or use it with other HTTP clients
final httpClient = HttpClient();
final request = await httpClient.getUrl(Uri.parse('https://your-api.com/protected-endpoint'));
request.headers.set('Cookie', '${sessionCookie.name}=${sessionCookie.value}');
final response = await request.close();
}
// For CSRF protection, include both session and CSRF tokens
final sessionToken = await client.getCookie('better-auth.session_token');
final csrfToken = await client.getCookie('better-auth.csrf_token');
if (sessionToken != null && csrfToken != null) {
final dio = Dio();
dio.options.headers['Cookie'] = '${sessionToken.name}=${sessionToken.value}; ${csrfToken.name}=${csrfToken.value}';
dio.options.headers['X-CSRF-Token'] = csrfToken.value;
// Now your requests are properly authenticated and CSRF-protected
final response = await dio.post('https://your-api.com/secure-action', data: {...});
}
Note: The SuperBetterAuth client automatically manages cookies for all built-in operations. Manual cookie handling is only needed when making custom API calls outside of the provided methods.
Error Handling #
final result = await client.signIn.email(
email: "user@example.com",
password: "wrongpassword"
);
if (result.isSuccess) {
print("Welcome ${result.data!.user.name}!");
} else {
// Handle different error types
switch (result.error?.code) {
case 'INVALID_CREDENTIALS':
showSnackBar("Invalid email or password");
break;
case 'USER_NOT_FOUND':
showSnackBar("No account found with this email");
break;
default:
showSnackBar("Login failed: ${result.error?.message}");
}
}
๐ฏ Full Example #
import 'package:flutter/material.dart';
import 'package:super_better_auth/super_better_auth.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await SuperBetterAuth.initialize(
url: 'your_base_url/api/auth',
);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return BetterAuthProvider(
child: MaterialApp(
title: 'BetterAuth',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: const MyHomePage(title: 'Better Auth'),
),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: BetterAuthConsumer(
builder: (context, client) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
spacing: 8,
children: <Widget>[
FilledButton(
onPressed: () async {
final result = await client.signIn.email(
email: "test@mail.com",
password: "123456788",
);
if (result.data != null) {
debugPrint(result.data.toString());
} else {
debugPrint(result.error?.message);
}
},
child: Text("Sign-in"),
),
FilledButton(
onPressed: () async {
final result = await client.getSession();
if (result.data != null) {
debugPrint(result.data.toString());
} else {
debugPrint(result.error?.message);
}
},
child: Text("GetSession"),
),
FilledButton(
onPressed: () {
client.signOut();
},
child: Text("SignOut"),
),
FilledButton(
onPressed: () async {
await client.signIn.social(
provider: 'github',
disableRedirect: true,
callbackURL: "/auth-callback",
callbackUrlScheme: "myapp",
);
},
child: Text("Github"),
),
FilledButton(
onPressed: () async {
final result = await client.signUp.email(
name: "test",
email: "test@mail.com",
password: "123456788",
);
if (result.data != null) {
debugPrint(result.data.toString());
} else {
debugPrint(result.error?.message);
}
},
child: Text("SignUp"),
),
// Organization Management Button
FilledButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(
builder: (_) => OrganizationExample()
));
},
child: Text("Organizations"),
),
// Cookie Management Button
FilledButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(
builder: (_) => CookieExample()
));
},
child: Text("Cookie Management"),
),
],
),
);
},
),
);
}
}
๐ฑ Example App #
The package includes a comprehensive example app demonstrating all features:
Running the Example #
- Clone the repository
- Navigate to the example directory:
cd example - Install dependencies:
flutter pub get - Configure your Better Auth server URL in
lib/main.dart - Run the app:
flutter run
Example Features #
The example app includes:
- Authentication Demo - Sign in/up with email, social providers
- Organization Management - Complete CRUD operations for organizations
- Cookie Inspector - View and manage authentication cookies
- Error Handling - Comprehensive error state management
- Real-time Updates - Live session state monitoring
File Structure #
example/
โโโ lib/
โ โโโ main.dart # Main app with authentication
โ โโโ organization_example.dart # Organization management UI
โ โโโ cookie_example.dart # Cookie management UI
โ โโโ .env # Environment configuration
๐ Social Authentication #
For social authentication, it is currently recommended to use idToken.
If the social provider does not support idToken, follow these steps:
-
Add the dependency:
Add
flutter_web_auth_2: ^5.0.0-alpha.3(or newer) to yourpubspec.yamldependencies. -
Update your AndroidManifest.xml:
Insert the following into your
AndroidManifest.xml, replacingYOUR_CALLBACK_URL_SCHEME_HEREwith your actual callback URL scheme:
<manifest>
<application>
...
<activity
android:name="com.linusu.flutter_web_auth_2.CallbackActivity"
android:exported="true"
android:taskAffinity="">
<intent-filter android:label="flutter_web_auth_2">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="YOUR_CALLBACK_URL_SCHEME_HERE" />
</intent-filter>
</activity>
...
</application>
</manifest>
-
Configure your Better Auth server plugin:
Add
expo()from@better-auth/expoto your Better Auth server plugin. -
Add your callback scheme to trustedOrigins:
In your Better Auth configuration, ensure that
YOUR_CALLBACK_URL_SCHEME_HERE://is included in thetrustedOriginslist.
export const auth = betterAuth({
trustedOrigins: ["YOUR_CALLBACK_URL_SCHEME_HERE://"]
})
๐ API Reference #
Core Authentication Methods #
| Method | Description | Parameters |
|---|---|---|
signIn.email() |
Email/password sign in | email, password |
signIn.social() |
Social provider sign in | provider, callbackURL |
signUp.email() |
Email registration | name, email, password |
getSession() |
Get current session | None |
signOut() |
Sign out user | None |
Organization Methods #
| Method | Description | Parameters |
|---|---|---|
organization.createOrganization() |
Create new organization | name, slug?, logo? |
organization.getOrganization() |
Get organization by ID | organizationId |
organization.updateOrganization() |
Update organization | organizationId, data |
organization.deleteOrganization() |
Delete organization | organizationId |
organization.inviteMember() |
Invite user to org | organizationId, email, role |
organization.listMembers() |
List organization members | organizationId |
Cookie Management Methods #
| Method | Description | Returns |
|---|---|---|
getCookie(name) |
Get specific cookie | Cookie? |
getCookies() |
Get all cookies | List<Cookie> |
getAuthCookies() |
Get auth-related cookies | List<Cookie> |
hasCookie(name) |
Check if cookie exists | bool |
clearCookies() |
Clear all cookies | void |
๐ก๏ธ Security Best Practices #
Cookie Security #
- Never log or expose sensitive cookies in production
- Use
getAuthCookies()to filter only authentication-related cookies - Clear cookies on sign out:
await client.clearCookies()
Organization Access Control #
- Always verify user permissions before organization operations
- Use role-based access control for sensitive operations
- Validate organization membership before allowing access
Error Handling #
- Always check
result.isSuccessbefore accessingresult.data - Handle network errors gracefully with retry mechanisms
- Log errors for debugging but avoid exposing sensitive information
๐ง Configuration #
Initialize with Custom Options #
await SuperBetterAuth.initialize(
url: 'https://your-api.com/api/auth',
options: BetterAuthOptions(
timeout: Duration(seconds: 30),
retryCount: 3,
enableLogging: true, // Only in development
),
);
Environment Variables #
Create a .env file in your project root:
BETTER_AUTH_URL=https://your-api.com/api/auth
BETTER_AUTH_TIMEOUT=30000
BETTER_AUTH_ENABLE_LOGGING=false
๐งช Testing #
Unit Testing #
// Test authentication flow
testWidgets('should sign in user with email', (tester) async {
final client = SuperBetterAuth.client;
final result = await client.signIn.email(
email: 'test@example.com',
password: 'password123'
);
expect(result.isSuccess, true);
expect(result.data?.user.email, 'test@example.com');
});
Integration Testing #
The package includes comprehensive integration tests. Run them with:
flutter test integration_test/
๐ค Contributing #
We welcome contributions! Please see our Contributing Guide for details.
Development Setup #
- Fork the repository
- Clone your fork:
git clone https://github.com/yourusername/super_better_auth.git - Create a feature branch:
git checkout -b feature/amazing-feature - Install dependencies:
flutter pub get - Run tests:
flutter test - Make your changes and add tests
- Commit your changes:
git commit -m 'Add amazing feature' - Push to your branch:
git push origin feature/amazing-feature - Open a Pull Request
Code Generation #
After modifying models, run code generation:
flutter packages pub run build_runner build --delete-conflicting-outputs
๐ Changelog #
v1.2.0 - Latest #
- โ Organization Management - Complete organization, team, and member management
- โ
Cookie Management - Direct access to authentication cookies with
getCookie()method - โ Enhanced Error Handling - Improved error types and messages
- โ Type Safety - Generated models with JSON serialization
- โ Example App - Comprehensive example with all features
- ๐ Bug Fixes - Resolved null safety issues and improved stability
v1.1.0 #
- โ Plugin System - Modular architecture for Better Auth plugins
- โ Social Authentication - GitHub, Google, Discord support
- โ Admin Features - Administrative user management
- โ JWT Support - Token-based authentication
v1.0.0 #
- โ Core Authentication - Email, phone, username authentication
- โ Session Management - User session handling
- โ Flutter Integration - Provider pattern with BetterAuthConsumer
๐ License #
This project is licensed under the MIT License - see the LICENSE file for details.
๐ฅ Authors #
- Primary Author: Bijoy Haldar
- Original Author: Tsiresy Milร
- Contributors: See CONTRIBUTORS.md
๐ Acknowledgments #
- Better Auth team for the excellent authentication framework
- Flutter community for continuous inspiration and support
- All contributors who help improve this package
๐ Support #
- ๐ง Email: hi@bijoy.work
- ๐ Issues: GitHub Issues
- ๐ฌ Discussions: GitHub Discussions
- ๐ Documentation: API Docs
Made with โค๏ธ for the Flutter community
โญ Star this repo โข ๐ Report Bug โข ๐ก Request Feature