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() 替换原有异常...

上一篇 下一篇

猜你喜欢

热点阅读