🐙

Flutterのwebviewについて、とCookieの永続化

2025/02/23に公開

Flutter webviewを利用する機会があったので記録しておきます。iOS、Androidのそれぞれの仕様が異なるため、複雑になっています。

Flutter webviewとは

Flutterにおけるwebviewは本来、ブラウザで閲覧できるサイトをアプリ内で閲覧できるようにするものです。これによって、アプリから簡単にセッションなどを維持し、WEBアプリで実装された機能を利用できます。

ユースケース

  • ネイティブアプリの画面の開発は最小限にして、必要な際にはWEBアプリの機能を使用する。
  • 端末管理などの関係で、ネイティブアプリが必要だが、開発コストが高いのでWEBアプリの機能をまるごと利用する。
  • 決済、認証などでサードパーティのものを使用するために本来ブラウザで閲覧するものを埋め込んで利用する。

flutter_webviewとinapp_webview

Flutterには純正のflutter_webviewと、サードパーティーのflutter_inapp_webviewが存在します。
後者の方が高機能で使いやすいですが、かなりバグが多いようです。
今回、はアプリ終了時のCookieの保存(永続化)と埋め込んだサイトのJavaScriptのCookieアクセスについて実際に動かしてみたのでその結果をまとめます。

検証環境

ソフトウェア webview
flutter 3.6.2
webview 4.10.0
inapp_webview 6.0.0
dotenv 5.2.1
Android 14.3
iOS 17.5

サイトのJavaScriptのCookieアクセス

OS webview inappwebview
Android 不可能 可能
iOS 可能 可能

AndroidのwebviewにおいてはJavScriptからDartへの通信が制限されていると考えられます。

アプリ再起動時のCookie保持

OS webview inappwebview
Android 保持 保持
iOS 非保持 非保持

iOSにおけるCookie保持(永続化)

検証結果からわかる通り、iOSではサイトの Cookie情報が保持できません。ログインなどで Cookieを利用する際にはどのようにすればいいでしょうか?

Cookieを取得

webview、inappwebviewどちらにも CookieManagerという機能が存在し、アプリからサイトのCookie情報にアクセスできます。まずはこれを利用してアプリ側でCookie情報を扱えるようにします。

CookieManager cookieManager = CookieManager.instance();
Object obj = await cookieManager.getCookie(
    url: WebUri("https://example.com"),
    name: "{Cookiename}",
) ?? "";
Cookie data = obj as Cookie;

Cookieをストレージへ保存

取得したCookieは本体に保存する必要があります。shared_preferencesが利用されるケースが多いようですが、セッショントークンなどの機密情報の高い情報ではどうでしようか?
そこで、secure_storageを利用します。このデータは暗号化して保存されます。
データはKey:Valueの形で保存されます。

final storage = FlutterSecureStorage();
await storage.write(
    key: "{Keyname}",
    value: {Cookievalue},
);

Cookieをストレージから取得

Key:Valueで保存されているので簡単に取得できます。

final storage = FlutterSecureStorage();
String data = await storage.read(key: "{Keyname}") ?? "";

Cookieをサイトに設定

Key:Valueで保存されているので簡単に取得できます。

CookieManager cookieManager = CookieManager.instance();
final expiresDate = DateTime
    .now()
    .add(Duration(days: 7)) //有効期間
    .millisecondsSinceEpoch;
await cookieManager.setCookie(
    url: WebUri("https://example.com"),
    name: "{Cookiename}",
    value: "{Cookievalue}",
    expiresDate: expiresDate,
    isSecure: true,
);

実行のタイミング

これが迷ったポイントです。Cookieの永続化において必要なプロセスとパフォーマンスの低下を考慮した結果、以下のような処理とタイミングで行うことにしました。

  • Cookieを取得(各ページロード時)
  • Cookieをストレージへ保存(各ページロード時)
  • Cookieをストレージから取得(アプリ開始時)
  • Cookieをサイト用に設定(アプリ開始時)

上2つについてはアプリ終了時に動作させられるのが理想なのですが、ライフサイクルの監視などを試してみたところ特にiOSにおいてバッググラウンドの処理などの関係で確実に動作させることが難しいと判断しました。

以上、Flutterにおけるwebviewについでした!Flutterは初めて触ったので今後も活用できればと!

Discussion