老铁记得 转发 ,猫哥会出现更多 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 {}被调用时。所以你的心田
- Check the error code(401), 查看错误代码(401) ,
- Get new access token 获取新的拜访令牌
await refreshToken();
下面的代码将调用 refreshToken 办法并在存储库中存储新的刷新和拜访令牌。(对于存储库,您能够应用 secure storage or shared preferences)
- 复制前一个申请并设置新的拜访令牌
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"] = "*/*";
- 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...