如何使用拦截器flutter处理标头中的令牌保存?

问题描述 投票:0回答:1

有一个使用

Injectable
包进行依赖注入的 Dart 项目。我面临三个类之间的循环依赖问题:
TokenInterceptor
AuthRepository
ApiDatasource
,这会导致依赖项初始化期间出现堆栈溢出错误。

代码结构如下:

注册模块.dart:

  @module
  abstract class RegisterModule {
    @lazySingleton
    Dio dio() => Dio(
          BaseOptions(baseUrl: Const.baseUrl),
        )..interceptors.addAll(
            [
              LogInterceptor(),
              TokenInterceptor(authRepository: ),
            ],
          );
  }

api_datasource.dart:

part 'api_datasource.g.dart';

@lazySingleton
@RestApi(baseUrl: Const.baseUrl)
abstract class ApiDatasource {

  @POST('/identity/Auth/userRegister')
  Future<void> registerUser(@Body() RegisterModel registerModel);

  @POST('/identity/Auth/userLogin')
  Future<void> loginUser(
    @Body() LoginModel loginModel,
  );

  @GET('/identity/Auth/resetPassword')
  Future<void> resetPassword(
    @Body() ResetPasswordModel resetPasswordModel,
  );

  @GET('/identity/Auth/setNewPassword/{token}')
  Future<void> setNewPassword(
    @Path() String token,
    @Body() SetNewPasswordModel setNewPasswordModel,
  );

  @GET('/pet/advertisements/shelters/{longitude}/{latitude}')
  Future<List<PetModel>> getAdvertisement(
    @Path('longitude') double longitude,
    @Path('latitude') double latitude,
    @Query('type') String type,
    @Query('gender') String gender,
    @Query('pageNumber') int pageNumber,
    @Query('pageSize') int pageSize,
  );

  @GET('/pet/advertisements/shelters/{petId}/{longitude}/{latitude}')
  Future<List<PetCardModel>> getDetailsAdvertisement(
    @Path('longitude') double longitude,
    @Path('latitude') double latitude,
    @Path('petId') double petId,
  );
}

token_interceptor.dart:

 class TokenInterceptor extends Interceptor {
  TokenInterceptor({required this.authRepository});
  final AuthRepository authRepository;
  @override
  Future<void> onRequest(
      RequestOptions options, RequestInterceptorHandler handler) async {
    final String? token = await authRepository.accessToken;
    if (token != null) {
      options.headers['Authorization'] = 'Bearer $token';
    }
    handler.next(options);
  }
}

auth_repository.dart:

       const _accessTokenKey = 'access_token';

    @lazySingleton
    class AuthRepository {
      AuthRepository(this.apiDatasource);

      final LappkaApiDatasource apiDatasource;

      String? _accessToken;

      FutureOr<String?> get accessToken async {
        if (_accessToken != null) {
          return _accessToken;
        }
        return readAccessToken().then((token) {
          _accessToken = token;
          return token;
        });
      }

      Future<String?> readAccessToken() async {
        try {
          const secureStorage = FlutterSecureStorage();
          return secureStorage.read(key: _accessTokenKey);
        } catch (e) {
          return null;
        }
      }


  Future<bool> saveToken(String token) async {
    try {
      const secureStorage = FlutterSecureStorage();
      await secureStorage.write(key: _accessTokenKey, value: token);
      _accessToken = token;
      return true;
    } catch (e) {
      return false;
    }
  }

  Future<void> registerUser(RegisterModel registerModel) async {
    await apiDatasource.registerUser(registerModel);
  }

  Future<void> loginUser(LoginModel loginModel) async {
    await apiDatasource.loginUser(loginModel);
  }

  Future<void> resetPassword(ResetPasswordModel resetPasswordModel) async {
    await apiDatasource.resetPassword(resetPasswordModel);
  }

  Future<void> setNewPassword(
      String token, SetNewPasswordModel setNewPasswordModel) async {
    await apiDatasource.setNewPassword(token, setNewPasswordModel);
  }
}

TokenInterceptor
依赖于
AuthRepository
AuthRepository
依赖于
ApiDatasource
,而
TokenInterceptor
又依赖于

TokenInterceptor

,从而创建了一个循环依赖循环。

我已经尝试使用Factory注入来延迟其实例化,但仍然遇到堆栈溢出问题。

如何解决这种循环依赖并防止依赖注入过程中的堆栈溢出?

谢谢您的帮助!

flutter rest android-studio retrofit dio
1个回答
0
投票

解决方案非常简单。只需创建另一个存储库,例如

token_repository

© www.soinside.com 2019 - 2024. All rights reserved.