auth

Authentication package with email/password login, OAuth providers, JWT tokens, and PostgreSQL/SQLite support.

Features

  • Email/password registration and login
  • OAuth2 provider integration (Google, GitHub, custom) with PKCE support
  • JWT access tokens with configurable expiry
  • Refresh token rotation with revocation
  • Password hashing via bcrypt with strength validation
  • Account linking (OAuth to existing email accounts)
  • Shelf middleware for token validation
  • PostgreSQL and SQLite repository implementations

Installation

dependencies:
  auth: ^1.0.0

Usage

Setup

import 'package:auth/auth.dart';

final authService = AuthService(
  accountRepository: PostgresAccountRepository(pool),
  passwordService: PasswordService(),
  tokenService: TokenService(
    accessTokenSecret: env.getString('JWT_SECRET'),
    issuer: 'myapp',
  ),
  oauthService: OAuthService(),
  userService: myUserService,
);

Registration

final result = await authService.register(
  email: 'user@example.com',
  password: 'SecurePass123',
  profileData: {'first_name': 'John', 'last_name': 'Doe'},
);
// result.account, result.tokens, result.user

Login

final result = await authService.login(
  email: 'user@example.com',
  password: 'SecurePass123',
);

OAuth Flow

// Register a provider
authService.oauthService.registerProvider(
  OAuthProvider.google,
  OAuthProviderConfig(
    clientId: env.getString('GOOGLE_CLIENT_ID'),
    clientSecret: env.getString('GOOGLE_CLIENT_SECRET'),
    authorizationEndpoint: Uri.parse(
      'https://accounts.google.com/o/oauth2/v2/auth',
    ),
    tokenEndpoint: Uri.parse('https://oauth2.googleapis.com/token'),
    redirectUri: Uri.parse('https://myapp.com/auth/google/callback'),
    scopes: ['openid', 'email', 'profile'],
  ),
);

// Get authorization URL
final authUrl = authService.getOAuthAuthorizationUrl(OAuthProvider.google);

// Handle callback
final result = await authService.handleOAuthCallback(
  OAuthProvider.google, callbackUri,
);

Token Management

// Refresh tokens
final newTokens = await authService.refreshAccessToken(refreshToken);

// Verify a token
final (account, user, scopes, clientId) =
    await authService.verifyAccessToken(token);

// Logout (revoke refresh token)
await authService.logout(refreshToken);

// Logout everywhere
await authService.logoutAll(accountId);

Shelf Middleware

final handler = Pipeline()
    .addMiddleware(authExceptionMiddleware())
    .addMiddleware(authMiddleware(authService))
    .addHandler(myRouter);

// In your handler:
Response handleRequest(Request request) {
  final account = request.account;
  final user = request.user;
  return Response.ok('Hello ${account.email}');
}

Available middleware:

  • authMiddleware() — validates Bearer token, attaches account/user
  • optionalAuthMiddleware() — allows unauthenticated requests
  • requireAccountMiddleware() — rejects unauthenticated requests
  • requireUserMiddleware() — rejects requests without a user profile
  • authExceptionMiddleware() — converts auth exceptions to JSON