共计 4365 个字符,预计需要花费 11 分钟才能阅读完成。
老铁记得 转发,猫哥会出现更多 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 variable
response = 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…