jwt_hero 0.1.0
jwt_hero: ^0.1.0 copied to clipboard
JWT Hero is a Flutter package that helps you to manage JWT tokens in your Flutter app.
JWT Hero #
JWT Hero is a Dart package that provides an easy way to handle JWT token management, including token validation, refresh, and retrying failed requests. This package is designed to work seamlessly with the Dio HTTP client.
Installation #
Add jwt_hero
to your pubspec.yaml
file:
dependencies:
jwt_hero: ^0.1.0
Then, run flutter pub get to install the package.
Setting Up #
To use JwtHeroInterceptor, you need to set up a few components:
- Token Storage: Implement the TokenStorage interface to define how tokens are stored and retrieved.
- Refresh Logic: Provide a callback to handle token refresh logic.
- Session Management: Optionally, manage session expiration.
Example #
Here is a complete example of how to set up and use JwtHeroInterceptor. As a first step, you need to implement the TokenStorage interface:
const _accessToken = 'accessToken';
const _refreshToken = 'refreshToken';
final class SecureTokenStorage implements TokenStorage {
SecureTokenStorage(this.secureStorage);
final FlutterSecureStorage secureStorage;
final _controller = StreamController<JwtToken?>.broadcast();
@override
Future<JwtToken?> loadToken() async {
final accessToken = await secureStorage.read(key: _accessToken);
final refreshToken = await secureStorage.read(key: _refreshToken);
if (accessToken != null && refreshToken != null) {
return JwtToken(
accessToken: accessToken,
refreshToken: refreshToken,
);
}
return null;
}
@override
Future<void> saveToken(JwtToken jwtToken) async {
await secureStorage.write(
key: _accessToken,
value: jwtToken.accessToken,
);
await secureStorage.write(
key: _refreshToken,
value: jwtToken.refreshToken,
);
_controller.add(jwtToken);
}
@override
Future<void> clearToken() async {
await secureStorage.delete(key: _accessToken);
await secureStorage.delete(key: _refreshToken);
}
@override
Future<void> close() => _controller.close();
@override
Stream<TokenPair?> getTokenStream() => _controller.stream;
@override
Future<String?> get accessToken => secureStorage.read(key: _accessToken);
@override
Future<String?> get refreshToken => secureStorage.read(key: _refreshToken);
}
Next, you need to provide a callback to handle token refresh logic and create an instance of JwtHeroInterceptor:
final dio = Dio();
dio.interceptors.add(
JwtHeroInterceptor(
tokenStorage: SecureTokenStorage(),
baseClient: dio,
onRefresh: (refreshClient, refreshToken) async {
refreshClient.options = refreshClient.options.copyWith(
headers: {'refresh-Token': refreshToken},
);
final response = await refreshClient.post('/refresh');
return JwtToken(
accessToken: response.data['accessToken'],
refreshToken: response.data['refreshToken'],
);
},
sessionManager: SessionExpirationManager(),
),
);
SessionManager #
You can inject SessionExpirationManager to your classes using Dependency Injection (DI) to listen sessionStatus. And if user login/register successfully, we should call sessionManager.startSession() to start the session.
Handling Token Expiration #
The JWTHeroInterceptor automatically handles token expiration and refresh. If a request fails with a 401 status code, the interceptor will attempt to refresh the token and retry the request.