dartapi_auth 0.0.10
dartapi_auth: ^0.0.10 copied to clipboard
DartAPI Auth is a lightweight and extensible authentication package for Dart backend applications. It provides JWT-based authentication with Auth Middleware.
dartapi_auth #
JWT authentication and API key middleware for the DartAPI ecosystem. Supports HS256 (symmetric) and RS256 (asymmetric) signing, token revocation, and static API key validation.
Installation #
dependencies:
dartapi_auth: ^0.0.6
JwtService (HS256) #
Use HS256 for single-service deployments where the signing and verification key can stay on one server:
final jwtService = JwtService(
accessTokenSecret: 'my-access-secret',
refreshTokenSecret: 'my-refresh-secret',
issuer: 'my-app',
audience: 'api-clients',
);
JwtService (RS256) #
Use RS256 when multiple services need to verify tokens without sharing the signing key. Distribute the public key freely; keep the private key server-side only.
final jwtService = JwtService.rs256(
privateKeyPem: File('private.pem').readAsStringSync(),
publicKeyPem: File('public.pem').readAsStringSync(),
issuer: 'my-app',
audience: 'api-clients',
);
Generating Tokens #
final accessToken = jwtService.generateAccessToken(claims: {
'sub': 'user-123',
'username': 'akash',
});
final refreshToken = jwtService.generateRefreshToken(accessToken: accessToken);
Verifying Tokens #
Both methods are async and return null on any failure (expired, wrong issuer, invalid signature, revoked):
final payload = await jwtService.verifyAccessToken(accessToken);
if (payload == null) {
// token is invalid
}
final refreshPayload = await jwtService.verifyRefreshToken(refreshToken);
Token Revocation #
Inject a TokenStore to enable revocation. InMemoryTokenStore works for single-instance servers:
final jwtService = JwtService(
accessTokenSecret: 'my-secret',
refreshTokenSecret: 'my-refresh-secret',
issuer: 'my-app',
audience: 'api-clients',
tokenStore: InMemoryTokenStore(),
);
await jwtService.revokeToken(accessToken);
final payload = await jwtService.verifyAccessToken(accessToken); // null
For distributed deployments, implement TokenStore against Redis or a database:
class RedisTokenStore implements TokenStore {
final RedisClient client;
RedisTokenStore(this.client);
@override
Future<void> revoke(String jti) => client.set('revoked:$jti', '1');
@override
Future<bool> isRevoked(String jti) async =>
await client.get('revoked:$jti') != null;
}
Protecting Routes #
Pass authMiddleware to any route's middlewares list:
ApiRoute<void, List<UserDTO>>(
method: ApiMethod.get,
path: '/users',
typedHandler: getUsers,
middlewares: [authMiddleware(jwtService)],
);
The verified JWT payload is available in the handler via request.context['user']:
Future<UserDTO> getProfile(Request request, void _) async {
final user = request.context['user'] as Map<String, dynamic>;
final userId = user['sub'] as String;
// ...
}
API Key Middleware #
Use apiKeyMiddleware to protect routes with a static key — suitable for webhooks or internal service-to-service calls:
ApiRoute(
method: ApiMethod.post,
path: '/webhooks/stripe',
middlewares: [
apiKeyMiddleware(validKeys: {'whsec_abc123'}),
],
typedHandler: handleStripeWebhook,
)
The default header is X-API-Key. Override with headerName:
apiKeyMiddleware(
validKeys: {'my-internal-key'},
headerName: 'X-Internal-Token',
)
The validated key is stored in request.context['api_key'] for downstream handlers.
Links #
License #
BSD 3-Clause License © 2025 Akash G Krishnan