我尝试使用 grpc (使用 protobuf)和拦截器在 flutter 中实现身份验证。我现在陷入处理过期的 accessToken 的困境,我想刷新令牌并刷新令牌。刷新后,应该再次调用该函数,因此实际函数不会注意到过期的令牌。
这是我的AuthClient
final channel = ClientChannel(
grpcHost,
port: grpcPort,
options: ChannelOptions(
credentials: const ChannelCredentials.insecure(),
codecRegistry:
CodecRegistry(codecs: const [GzipCodec(), IdentityCodec()]),
),
);
_client = AuthServiceClient(channel,
interceptors: [AuthenticationInterceptor()]);
AuthClient正在使用这个ClientInterceptor
class AuthenticationInterceptor extends ClientInterceptor {
final storage = const FlutterSecureStorage();
FutureOr<void> _provider(Map<String, String> metadata, String uri) async {
final accessToken = await storage.read(key: 'accessToken');
metadata['Authorization'] = accessToken ?? "";
}
@override
ResponseFuture<R> interceptUnary<Q, R>(
ClientMethod<Q, R> method, Q request, CallOptions options, invoker) {
return super.interceptUnary(method, request,
options.mergedWith(CallOptions(providers: [_provider])), invoker)
..catchError((e) async {
if (e is GrpcError) {
if (e.code == StatusCode.invalidArgument &&
e.message == "Invalid auth token") {
await refreshTheToken();
return super.interceptUnary(
method,
request,
options.mergedWith(CallOptions(providers: [_provider])),
invoker);
}
}
throw e;
});
}
}
我这样称呼客户
loadUser() async {
print("Loading user");
_status = AuthStatus.uninitialized;
try {
StatusRequest statusRequest = StatusRequest();
final status = await _client!.status(statusRequest);
_status = AuthStatus.authenticated;
_currentUser = User(status.user.id, status.user.username);
} catch (e) {
print(e);
_status = AuthStatus.unauthenticated;
} finally {
notifyListeners();
}
}
我期望使用
await refreshTheToken();
和 return super.interceptUnary
我可以刷新令牌,然后再次调用该函数,而不会在 loadUser
函数中出现错误。
然而,实际行为是,在
loadUser
中的 catchError
可以处理错误并刷新令牌之前,interceptUnary
函数会引发错误。
我遇到了同样的问题。你找到解决办法了吗?