Dio对象在App请求中一般在单例对象中使用,用来与后端进行普通的网络请求,如POST\GET等。Dio支持使用拦截器对所有的请求进行拦截,从而进行特殊处理,如增加token参数、请求和响应日志记录等。参考代码片段:
引用头文件:
import 'package:dio/dio.dart';
import 'interceptor/http_interceptor.dart';
在类的构造中,添加自定义的拦截器:
class ThingsboardClient {
///......
factory ThingsboardClient() {
var dio = Dio();
dio.options.baseUrl = apiEndpoint;
dio.interceptors.clear();
dio.interceptors.add(HttpInterceptor());
///......
}
自定义的拦截器,拦截所有的API类型的请求,并添加token:
class HttpInterceptor extends Interceptor {
static const String _authScheme = 'Bearer ';
static const _authHeaderName = 'X-Authorization';
///...
@override
Future onRequest(
RequestOptions options, RequestInterceptorHandler handler) async {
if (options.path.startsWith('/api/')) {
var config = _getInterceptorConfig(options);
var isLoading = !_isInternalUrlPrefix(options.path);
if (!config.isRetry) {
_updateLoadingState(config, isLoading);
}
///路径是否需要token
if (_isTokenBasedAuthEntryPoint(options.path)) {
///token是否有效
if (_tbClient.getJwtToken() == null &&
!_tbClient.refreshTokenPending()) {
return _handleRequestError(
options, handler, ThingsboardError(message: 'Unauthorized!'));
} else if (!_tbClient.isJwtTokenValid()) {
///token不可用,返回错误,刷新token后,重新提交请求
return _handleRequestError(
options, handler, ThingsboardError(refreshTokenPending: true));
} else {
///处理请求,添加token等头信息
return _jwtIntercept(options, handler);
}
} else {
return _handleRequest(options, handler);
}
} else {
return handler.next(options);
}
}
///需要启用token的路径
bool _isTokenBasedAuthEntryPoint(String url) {
return url.startsWith('/api/') &&
!url.startsWith(Constants.entryPoints['login']!) &&
!url.startsWith(Constants.entryPoints['tokenRefresh']!) &&
!url.startsWith(Constants.entryPoints['nonTokenBased']!);
}
bool _updateAuthorizationHeader(RequestOptions options) {
var jwtToken = _tbClient.getJwtToken();
if (jwtToken != null) {
options.headers[_authHeaderName] = _authScheme + jwtToken;
return true;
} else {
return false;
}
}
Future _jwtIntercept(
RequestOptions options, RequestInterceptorHandler handler) async {
///更新头授权token等信息
if (_updateAuthorizationHeader(options)) {
return _handleRequest(options, handler);
} else {
return _handleRequestError(options, handler,
ThingsboardError(message: 'Could not get JWT token from store.'));
}
}
///...
}