Handling HTTP Requests with DIO and Refresh Tokens in Flutter
Tags: flutter, dart, dio, http
Published: 2023-03-26 13:00:12

In this article, we'll demonstrate how to use the DIO package to make GET and POST requests in a Flutter application, while leveraging refresh tokens to maintain a persistent user session. We'll cover the following topics:

1. Setting up DIO
2. Creating a DIO instance with interceptors
3. Making GET and POST requests
4. Implementing automatic token refresh with DIO interceptors


**1. Setting up DIO**
First, add the DIO package to your pubspec.yaml file:

```
dependencies:
  flutter:
    sdk: flutter
  dio: ^4.0.0
```
Then, run flutter packages get to install the package.


**2. Creating a DIO instance with interceptors**
To create a DIO instance with interceptors, first import the DIO package:
`import 'package:dio/dio.dart';`

Then, create a DIO instance with a default configuration:

```
Dio dio = Dio(
  BaseOptions(
    baseUrl: 'https://your-api-url.com',
    connectTimeout: 5000,
    receiveTimeout: 3000,
  ),
);
```


**3. Making GET and POST requests**
Now that we have a DIO instance, we can use it to make GET and POST requests. Here's an example of making a GET request:

```
Future<void> fetchData() async {
  try {
    Response response = await dio.get('/path/to/your/endpoint');
    print(response.data);
  } on DioError catch (e) {
    print(e.message);
  }
}
```
To make a POST request, we can use the post method as shown below:

```
Future<void> postData() async {
  try {
    Response response = await dio.post(
      '/path/to/your/endpoint',
      data: {'key': 'value'},
    );
    print(response.data);
  } on DioError catch (e) {
    print(e.message);
  }
}
```


**4. Implementing automatic token refresh with DIO interceptors**
To implement automatic token refresh, we'll add an interceptor to the DIO instance. This interceptor will handle token refresh logic whenever it detects a 401 (Unauthorized) response from the server.

First, create a function to refresh the access token:

```
Future<String> refreshToken() async {
  // Perform a request to the refresh token endpoint and return the new access token.
  // You can replace this with your own implementation.
  return 'your_new_access_token';
}
```
Next, add an interceptor to the DIO instance:

```
dio.interceptors.add(
  InterceptorsWrapper(
    onRequest: (options, handler) {
      // Add the access token to the request header
      options.headers['Authorization'] = 'Bearer your_access_token';
      return handler.next(options);
    },
    onError: (DioError e, handler) async {
      if (e.response?.statusCode == 401) {
        // If a 401 response is received, refresh the access token
        String newAccessToken = await refreshToken();

        // Update the request header with the new access token
        e.requestOptions.headers['Authorization'] = 'Bearer $newAccessToken';

        // Repeat the request with the updated header
        return handler.resolve(await dio.fetch(e.requestOptions));
      }
      return handler.next(e);
    },
  ),
);
```
With this interceptor in place, your application will automatically refresh the access token and retry requests whenever a `401 response` is received.

That's it! You've now implemented a DIO instance with interceptors for handling GET and POST requests, as well as automatic token refresh. This will help you maintain a persistent user session and improve the user experience in your Flutter application.