Skip to content

Instantly share code, notes, and snippets.

@ehbc221
Last active June 8, 2023 16:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ehbc221/fcf5240803d68a963418374f59d8b7da to your computer and use it in GitHub Desktop.
Save ehbc221/fcf5240803d68a963418374f59d8b7da to your computer and use it in GitHub Desktop.
An interceptor for JWTs in Flutter, using dio and shared_preferences libraries. Handles retrieving the JWT in shared_preferences (when exists) and adding it to the request
import 'package:dio/dio.dart';
import 'package:expenza/config/injectable.dart';
import 'package:expenza/domain/user_preferences.dart';
import 'package:expenza/utils/log.utils.dart';
const String _tag = 'JwtInterceptor';
/// Jwt Interceptor.
///
/// This class provides the Jwt from the user's session to the request's header
/// authorization if exists.
///
/// - author - @ehbc221
/// - version - 1.0.0
/// - last updated - June 8th, 2023
class JwtInterceptor extends Interceptor {
@override
Future<void> onRequest(
RequestOptions options,
RequestInterceptorHandler handler,
) async {
logD(_tag, 'onRequest called.');
// Check if the user has a Jwt in sharedPreferences
final String? authToken = getIt<UserPreferences>().getAuthJWT()?.idToken;
// Get the token from the user's session
if (authToken != null) {
final Map<String, String> authorizationHeader = <String, String>{
'Authorization': 'Bearer $authToken'
};
// Add Jwt to the request
options.headers.addAll(authorizationHeader);
}
// Call the next interceptor
return handler.next(options);
}
}
@ehbc221
Copy link
Author

ehbc221 commented Jun 8, 2023

Example

Your can chain this interceptor with others when building your API configuration with dio.

import 'package:dio/dio.dart';
import 'package:expenza/config/app_config.dart';
import 'package:expenza/domain/models/type/json_map.type.dart';
import 'package:expenza/network/interceptors/jwt.interceptor.dart';
import 'package:expenza/utils/log.utils.dart';
import 'package:injectable/injectable.dart';

const String _tag = 'ApiBuilder';

/// Application's Api Builder: handles configurations and interceptors.
@injectable
class ApiBuilder {
  /// Get an instance of the http client to perform api requests.
  Dio getHttpClient({
    String? authToken,
    String contentType = 'application/json',
    JsonMap? queryParameters,
    JsonMap? extra,
    JsonMap? headers,
    ResponseType? responseType = ResponseType.json,
  }) {
    logD(_tag, 'getHttpClient called.');
    // Dio options
    final BaseOptions options = BaseOptions(
      baseUrl: appConfig.baseUrl,
      contentType: 'application/json; charset=utf-8',
      connectTimeout: const Duration(seconds: 30),
      receiveTimeout: const Duration(seconds: 30),
      queryParameters: queryParameters,
      extra: extra,
      headers: headers,
    );
    // Init Dio with BaseOptions
    final Dio dio = Dio(options);
    // Add interceptors
    dio.interceptors.addAll(<Interceptor>[
      LogInterceptor(
        responseBody: true,
        requestBody: true,
      ),
      JwtInterceptor(), // <----- The interceptor is used here
    ]);
    return dio;
  }
}

@ehbc221
Copy link
Author

ehbc221 commented Jun 8, 2023

Please note that you can replace the JWT provider (we are using shared_preferences here) with the one you like.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment