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

wgeznvg7  于 2023-10-22  发布在  Flutter
关注(0)|答案(1)|浏览(122)

我有一个使用Injectable包进行依赖注入的Dart项目。我面临着三个类之间的循环依赖问题:TokenInterceptorAuthRepositoryApiDatasource,这会导致依赖项初始化期间出现堆栈溢出错误。
代码结构如下:
register_module.dart:

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

API_API.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依赖于AuthRepositoryAuthRepository依赖于ApiDatasource,而ApiDatasource又依赖于TokenInterceptor,从而创建了一个循环依赖循环。
我已经尝试使用TokenInterceptor的工厂注入来延迟它的示例化,但我仍然遇到堆栈溢出问题。
如何解决这种循环依赖并防止依赖注入过程中的堆栈溢出?
谢谢您的帮助!

o3imoua4

o3imoua41#

解决办法很简单。创建一个类似token_repository的仓库。

相关问题