2020/5/17 更新
どうやらiOS13以降だと↓の通りの記述を入れても HandshakeException が発生するようです。
https://support.apple.com/ja-jp/HT210176
公式でのアナウンスもあり、クライアントの努力で解決するのは実質不可能と思われます。
正規の証明書発行することをオススメします。
はじめに
gRPCをFlutter(Dart)で使うときにオレオレ証明書で死ぬほど躓いたのでメモ。
オレオレ証明書のための HogeClient
の設定までにつまづいたこと、そしてどう修正していったのかを順を追って説明していきます。
目次
1. pbgrpc.dart
がない
2. SocketException
3. HandshakeException
4. 黙ってクラッシュ
5. 動いた
#1. pbgrpc.dart
がない
生成の設定ミスです。設定については割愛します。
#2. SocketException
実際のコード
_createClient() {
final channel = ClientChannel('https://hoge.com');
return HogeClient();
}
エラー
Unhandled Exception: gRPC Error (14, Error connecting: SocketException: Failed host lookup: 'https://hoge.com' (OS Error: nodename nor servname provided, or not known, errno = 8))
原因
https://
は不要でした。
#3. HandshakeException
実際のコード
_createClient() {
final channel = ClientChannel('hoge.com');
return HogeClient();
}
エラー
Unhandled Exception: gRPC Error (14, Error connecting: HandshakeException: Handshake error in client (OS Error:
CERTIFICATE_VERIFY_FAILED: ok(handshake.cc:354)))
原因
信頼できない証明書(オレオレ証明書)を使っていることによるエラーです。
#4. 黙ってクラッシュ
実際のコード
_createClient() {
final channel = ClientChannel(
'hoge.com',
options: ChannelOptions(
credentials: ChannelCredentials.insecure(),
),
);
return HogeClient();
}
エラー
Androidのみで出力されるエラー
Unhandled Exception: gRPC Error (2, HTTP/2 error: Connection error: Connection is being forcefully terminated. (errorCode: 10))
flutter run -vのクラッシュ直前抜粋
[ +5 ms] DevFS: Deleting filesystem on the device
(file:///Users/{ユーザ名とかデバイスIDとか}/)
[ +260 ms] Ignored error while cleaning up DevFS: TimeoutException after 0:00:00.250000: Future not completed
原因
ChannelCredentials.insecure(),
は認証をオフにするパラメータです。オレオレ証明書でも認証は必要なためクラッシュします。
#5. 動いた
実際のコード
_createClient() async {
final trustedRoot = await rootBundle.load('assets/key/api.pem');
final channelCredentials = ChannelCredentials.secure(
certificates: trustedRoot.buffer.asUint8List(),
);
final channel = ClientChannel(
'hoge.com',
options: channelOptions,
);
client = ClipServiceClient(channel);
}
ポイント
- 動かすためにオレオレ証明書の
.pem
が必要なため発行しましょう。 - assets内にそれを保存し
実際のコード
を参考にクライアントを生成しましょう。
感想
4.
でずっと黙ってクラッシュしてたので丸一日潰れました。
この記事によって誰かの丸一日が潰れることを阻止できれば本望。