Grpc-dart 不能处理 401
2021-01-30 本文已影响0人
gruan
JWT 如果判断 Token 失效, 会直接返回 401 . 但是在 Flutter 中, 无法处理...
catch 到的 GrpcError
一直是 unimplemented
, 而不是期待的unauthenticated
先用拦截器打印出 401 时响应的 headers.
{:status: 401, date: Sat, 30 Jan 2021 09:58:42 GMT, server: Kestrel, www-authenticate: Bearer, content-length: 0}
401 时, 返回 content-length: 0
.
在看看 Flutter 中 ResponseFuture
(\pub.flutter-io.cn\grpc-2.8.0\lib\src\client\common.dart) 的定义:
class ResponseFuture<R> extends DelegatingFuture<R>
with _ResponseMixin<dynamic, R> {
final ClientCall<dynamic, R> _call;
static R _ensureOnlyOneResponse<R>(R previous, R element) {
if (previous != null) {
throw GrpcError.unimplemented('More than one response received');
}
return element;
}
static R _ensureOneResponse<R>(R value) {
if (value == null) throw GrpcError.unimplemented('No responses received');
return value;
}
ResponseFuture(this._call)
: super(_call.response
.fold(null, _ensureOnlyOneResponse)
.then(_ensureOneResponse));
}
在父构造函数中, 首先判断的 _call.respnose
是不是收到多次, 其次判断它是不是为 null
.
这个地方如果先判断 _call.headers[":status"]
是不是 401 就可以了. 但是 _call.headers
又是一个 Future<Map<String,String>>
, 需要用到 async/await
, 但是在构造函数中, 使用异步???脑壳有点大...蛋疼...
我也尝试用拦截器:
import 'dart:developer';
import 'package:grpc/grpc.dart';
class AA extends ClientInterceptor {
///
@override
ResponseFuture<R> interceptUnary<Q, R>(ClientMethod<Q, R> method, Q request,
CallOptions options, ClientUnaryInvoker<Q, R> invoker) {
///
final call = super.interceptUnary(
method,
request,
options,
invoker,
);
call.then((v) {
log('aaaaaaaaaaaaaaaaaaaaaaa');
}).catchError((dynamic e) async {
var headers = await call.headers;
log(headers.toString());
if (headers.containsKey(":status") && headers[":status"] == "401") {
// throw GrpcError.unauthenticated();
//return null; //Future.error(GrpcError.unauthenticated());
}
}, test: (e) => e is GrpcError);
return call;
}
}
...
...
final client = ReportClient(
channel,
interceptors: List.filled(1, AA()),
);
但是 get 不到关键点, 无法用GrpcError.unauthenticated()
替换原有异常...