Be sure to retweet brother for more Flutter posts at ~~~~

Ducafecat WeChat group

B stationhttps://space.bilibili.com/40…

The original

https://medium.com/@wmnkrisha…

reference

  • https://pub.dev/packages/dio/…
  • https://pub.dev/packages/flut…
  • https://pub.dev/packages/shar…

The body of the

In this article, I’ll explain how to use Flutter Dio (4.0.0) for network calls and how to handle 401 when handling authorization using refresh tokens and access tokens in your Flutter application.

Before reading this article, I want you to have a basic understanding of shiver mobile application development.

Basic Authentication flow with refresh and access tokens

As you can see in the figure above, it is clear what the flow is when the refresh and access tokens are used in the authentication flow. After you log in, you get two tags called refresh and access. This access token expires quickly (the refresh token expires, too, but it will take more time than the access token). When you make a request with an expired access token, the status code 401(unauthorized) appears in the response. In this case, you must request a new token from the server and make the previous request again with a valid access token. If the refresh token has also expired, you must instruct the user to log in to the page and force him to log in again.

Dio class

class DioUtil { static Dio _instance; //method for getting dio instance Dio getInstance() { if (_instance == null) { _instance = createDioInstance(); } return _instance; } Dio createDioInstance() { var dio = Dio(); // adding interceptor dio.interceptors.clear(); dio.interceptors.add(InterceptorsWrapper(onRequest: (options, handler) { return handler.next(options); }, onResponse: (response, handler) { if (response ! = null) { return handler.next(response); } else { return null; } }, onError: (DioError e, handler) async { if (e.response ! = null) { if (e.response.statusCode == 401) {//catch the 401 here dio.interceptors.requestLock.lock(); dio.interceptors.responseLock.lock(); RequestOptions requestOptions = e.requestOptions; await refreshToken(); Repository repository = Repository(); var accessToken = await repository.readData("accessToken"); final opts = new Options(method: requestOptions.method); dio.options.headers["Authorization"] = "Bearer " + accessToken; dio.options.headers["Accept"] = "*/*"; dio.interceptors.requestLock.unlock(); dio.interceptors.responseLock.unlock(); final response = await dio.request(requestOptions.path, options: opts, cancelToken: requestOptions.cancelToken, onReceiveProgress: requestOptions.onReceiveProgress, data: requestOptions.data, queryParameters: requestOptions.queryParameters); if (response ! = null) { handler.resolve(response); } else { return null; } } else { handler.next(e); }}})); return dio; } static refreshToken() async { Response response; Repository repository = Repository(); var dio = Dio(); final Uri apiUrl = Uri.parse(BASE_PATH + "auth/reIssueAccessToken"); var refreshToken = await repository.readData("refreshToken"); dio.options.headers["Authorization"] = "Bearer " + refreshToken; try { response = await dio.postUri(apiUrl); if (response.statusCode == 200) { LoginResponse loginResponse = LoginResponse.fromJson(jsonDecode(response.toString()));  repository.addValue('accessToken', loginResponse.data.accessToken); repository.addValue('refreshToken', loginResponse.data.refreshToken); } else { print(response.toString()); //TODO: logout } } catch (e) { print(e.toString()); //TODO: logout } } }

This is the full course, and I will explain the most important parts.

Basically, as you can see in the createDioInstance method, you have to add an interceptor to catch the 401. When 401 occurs when error: (dioError e, handler) async {} is called. So your heart

  1. Check the error code(401),
  2. Get new access token
await refreshToken();

The above code calls the refreshToken method and stores the new refresh and access tokens in the repository. (For repositories, you can use Secure Storage or Shared Preferences)

  1. Copy the previous request and set the new access token
RequestOptions requestOptions = e.requestOptions;
Repository repository = Repository();
var accessToken = await repository.readData("accessToken");
final opts = new Options(method: requestOptions.method);
dio.options.headers["Authorization"] = "Bearer " + accessToken;
dio.options.headers["Accept"] = "*/*";
  1. Make the previous call again
final response = await dio.request(requestOptions.path,
    options: opts,
    cancelToken: requestOptions.cancelToken,
    onReceiveProgress: requestOptions.onReceiveProgress,
    data: requestOptions.data,
    queryParameters: requestOptions.queryParameters);

When you receive a reply, call it

handler.resolve(response);

The response is then sent to the location where you called the API, as shown below.

var dio = DioUtil().getInstance(); final String apiUrl = (BASE_PATH + "payments/addNewPayment/"); var accessToken = await repository.readData("accessToken"); dio.options.headers["Authorization"] = "Bearer " + accessToken; dio.options.headers["Accept"] = "*/*"; //response will be assigned to response variable response = await dio.post(apiUrl, data: event.paymentRequest.toJson());

Thats all. happy coding 🙂


The elder brother of the © cat

https://ducafecat.tech/

https://github.com/ducafecat

The issue of

Open source

GetX Quick Start

https://github.com/ducafecat/…

News Client

https://github.com/ducafecat/…

Strapi manual translation

https://getstrapi.cn

WeChat discussion group Ducafecat

A series of collections

The translation

https://ducafecat.tech/catego…

The open source project

https://ducafecat.tech/catego…

DART programming language basics

https://space.bilibili.com/40…

Flutter Zero Basics Beginners

https://space.bilibili.com/40…

Flutter combat news client from scratch

https://space.bilibili.com/40…

Flutter component development

https://space.bilibili.com/40…

Flutter Bloc

https://space.bilibili.com/40…

Flutter Getx4

https://space.bilibili.com/40…

Docker Yapi

https://space.bilibili.com/40…