老铁记得 转发 ,猫哥会出现更多 Flutter 好文~~~~

微信群 ducafecat

b 站 https://space.bilibili.com/40...

原文

https://medium.com/@wmnkrisha...

参考

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

注释

在本文中,我将解释如何应用 flutter dio (4.0.0)进行网络调用,以及如何在您的 flutter 应用程序中应用刷新令牌和拜访令牌来解决受权时解决 401。

在浏览这篇文章之前,我心愿你们对颤动挪动利用程序开发有一个根本的理解。

Basic Authentication flow with refresh and access tokens

正如您在下面的图中所看到的,很显著,在身份验证流中应用刷新和拜访令牌时的流程是什么。登录后,您将取得两个称为刷新和拜访的标记。此拜访令牌疾速过期(刷新令牌也过期,然而它将比拜访令牌破费更多的工夫)。当您应用过期的拜访令牌发出请求时,响应中会呈现状态码 401(未经受权)。在这种状况下,您必须从服务器申请一个新的令牌,并应用无效的拜访令牌再次收回上一个申请。如果刷新令牌也已过期,您必须批示用户登录页面并强制再次登录。

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    }  }}

以上是残缺的课程,我将解释其中最重要的局部。

次要是,正如您在 createDioInstance 办法中看到的,您必须增加一个拦截器来捕捉 401。当 401 产生在 error: (DioError e,handler) async {}被调用时。所以你的心田

  1. Check the error code(401), 查看错误代码(401) ,
  2. Get new access token 获取新的拜访令牌
await refreshToken();

下面的代码将调用 refreshToken 办法并在存储库中存储新的刷新和拜访令牌。(对于存储库,您能够应用 secure storage or shared preferences)

  1. 复制前一个申请并设置新的拜访令牌
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);

一旦收到回复,就 call

handler.resolve(response);

而后响应将被发送到您调用 api 的地位,如下所示。

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 variableresponse = await dio.post(apiUrl, data: event.paymentRequest.toJson());

Thats all. happy coding :)


© 猫哥

https://ducafecat.tech/

https://github.com/ducafecat

往期

开源

GetX Quick Start

https://github.com/ducafecat/...

新闻客户端

https://github.com/ducafecat/...

strapi 手册译文

https://getstrapi.cn

微信探讨群 ducafecat

系列汇合

译文

https://ducafecat.tech/catego...

开源我的项目

https://ducafecat.tech/catego...

Dart 编程语言根底

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

Flutter 零根底入门

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

Flutter 实战从零开始 新闻客户端

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

Flutter 组件开发

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...