IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> flutter Dio插件的使用 (十三) -> 正文阅读

[游戏开发]flutter Dio插件的使用 (十三)

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.'));
    }
  }

   ///...
}

封装后的 get、post、delete代码示例:?


  Future<Response<T>> get<T>(
    String path, {
    Map<String, dynamic>? queryParameters,
    Options? options,
    CancelToken? cancelToken,
    ProgressCallback? onReceiveProgress,
  }) async {
    try {
      return await _dio.get(path,
          queryParameters: queryParameters,
          options: options,
          cancelToken: cancelToken,
          onReceiveProgress: onReceiveProgress);
    } catch (e) {
      throw toThingsboardError(e);
    }
  }

  Future<Response<T>> post<T>(
    String path, {
    data,
    Map<String, dynamic>? queryParameters,
    Options? options,
    CancelToken? cancelToken,
    ProgressCallback? onSendProgress,
    ProgressCallback? onReceiveProgress,
  }) async {
    try {
      return await _dio.post(path,
          data: data,
          queryParameters: queryParameters,
          options: options,
          cancelToken: cancelToken,
          onSendProgress: onSendProgress,
          onReceiveProgress: onReceiveProgress);
    } catch (e) {
      throw toThingsboardError(e);
    }
  }

  Future<Response<T>> delete<T>(
    String path, {
    data,
    Map<String, dynamic>? queryParameters,
    Options? options,
    CancelToken? cancelToken,
  }) async {
    try {
      return await _dio.delete(path,
          data: data,
          queryParameters: queryParameters,
          options: options,
          cancelToken: cancelToken);
    } catch (e) {
      throw toThingsboardError(e);
    }
  }

定义请求和应答对象:

class LoginRequest {
  String username;
  String password;

  LoginRequest(this.username, this.password);

  Map<String, dynamic> toJson() {
    return {
      'username': username,
      'password': password,
    };
  }
}

class LoginResponse {
  final String token;
  final String refreshToken;

  LoginResponse(this.token, this.refreshToken);

  LoginResponse.fromJson(Map<String, dynamic> json)
      : token = json['token'],
        refreshToken = json['refreshToken'];
}

提交请求(代码中为用户登录,并获取token和refreshToken):

 Future<LoginResponse> login(LoginRequest loginRequest,
      {RequestConfig? requestConfig}) async {
    var response = await post('/api/auth/login',
        data: jsonEncode(loginRequest),
        options: defaultHttpOptionsFromConfig(requestConfig));
    var loginResponse = LoginResponse.fromJson(response.data);
    await _setUserFromJwtToken(
        loginResponse.token, loginResponse.refreshToken, true);
    return loginResponse;
  }

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-04-04 12:42:53  更:2022-04-04 12:44:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年10日历 -2024/10/27 20:34:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码