6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

FlutterでHttpClientのDioを使用して認証情報などをクッキー(Cookie)に持たせる方法

Last updated at Posted at 2022-03-14

はじめに

自前で作成したバックエンドの認証機能をRest APIで呼び出して、その認証情報をFlutterでどうやって利用するかを考えた時に、クッキー(Cookies)を利用しようとなったので、FlutterではCookiesはどうやったら実装できるのか調べました
FlutterでのCookieの利用方法についてのナレッジを記載していきます

Cookie初歩形

まずFlutterでCookiesを利用したい場合はデフォルトクッキーが備わっています

Cookie利用の初歩形

import 'dart:io';

Cookie cookie = Cookie('name', 'value')

しかしこれだけではただのマップ型のインスタンス感があり、実用としては使いづらいです

外部パッケージ導入

通常Cookiieを使用したい場合はAPIを利用する場面であるので、中国製のDioというHttpClientのパッケージを利用します
また、DioとCookieをいい感じで利用できるようにしてくれるパッケージCookieJarやCookieManagerもインストールします

pubspec.yaml

dependencies:
  dio: ^4.0.4
  cookie_jar: ^3.0.1
  dio_cookie_manager: ^2.0.0
  path_provider: ^2.0.9

path_providerはdio_cookie_managerの説明書きにクッキーを永続化するなら入れろと書かれていました
永続化する場合はどうやらストレージにCookieを保管するためにパーミッションの設定が必要なようです
デフォルトでは読み取り専用になっているので書き込みもできるように設定が必要な模様

Cookie基本形その1

HttpClientのDioを利用したCookieの使い方としては以下の形が基本形その1となります

import 'dart:io';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:dio/dio.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart';


final Uri _uriHost = Uri.parse('ホスト');

Future auth() async {
   Dio dio = Dio();
   List<Cookie> cookies = [];

    dio.options.baseUrl = _uriHost.toString();
    dio.options.connectTimeout = 5000;
    dio.options.receiveTimeout = 3000;
    dio.options.contentType = 'application/json';

    try {
      CookieJar cookieJar = CookieJar();
      cookieJar.saveFromResponse(_uriHost, _cookies);
      dio.interceptors.add(CookieManager(cookieJar));
      final response = await dio.post(
          '/authen/jwt/create',
          data: {
            'email': email,
            'password': password,
          }
      );
      cookies = [ ..._cookies, Cookie('access_token', response.data['access']) ];
      List<Cookie> result = await cookieJar.loadForRequest(_uriHost);
      print(result);
    } catch(error) {
      message = '正しいEメールとパスワードを入力してください';
      print(error);
    }
  }

Cookie永続化

上の基本形のクッキーは永続的なインスタンスではないので、Cookiesをほかのメソッドやクラスからなどでも使いたいときはPersistCookieJarを使う
こちらがCookieを一番使うことを最も想定された使い方だと思います

認証情報をCookieへ格納して永続化する基本形
login.dart

import 'dart:io';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:dio/dio.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart';

import 'package:path_provider/path_provider.dart';


final Uri _uriHost = Uri.parse('http://ホスト'); // http://10.0.2.2:8000


Future auth() async {
    Dio dio = Dio();
    List<Cookie> cookies = [];

    dio.options.baseUrl = _uriHost.toString();
    dio.options.connectTimeout = 5000;
    dio.options.receiveTimeout = 3000;
    dio.options.contentType = 'application/json';

    try {

      Directory appDocDir = await getApplicationDocumentsDirectory();
      String appDocPath = appDocDir.path;
      PersistCookieJar cookieJar = PersistCookieJar(storage: FileStorage(appDocPath+"/.cookies/"));

      cookieJar.saveFromResponse(_uriHost, cookies);
      dio.interceptors.add(CookieManager(cookieJar));

      final response = await dio.post(
          '/authen/jwt/create',
          data: {
            'email': userModel.email,
            'password': password,
          }
      );

      cookies = [ ...cookies, Cookie('access_token', response.data['access']) ];
      cookieJar.saveFromResponse(_uriHost, cookies);

      List<Cookie> cookieList = await cookieJar.loadForRequest(_uriHost); // 格納されたクッキーを確認しているだけの処理
      print(cookieList);
    } catch(error) {
      message = '正しいEメールとパスワードを入力してください';
      print(error);
    }
  }

ここで格納されたクッキーのインスタンスは以下のようにするとほかのメソッドやクラスなどから参照できるようになる
これにより一度ログインしたときの認証情報を他のクラスで共有することができて、Cookieを便利に使えるようになった

永続化したCookie情報を他のメソッドやクラスなどから読み込む方法

上記で格納したCookie上に格納されている認証情報は以下のようにして取り出して利用することができる

例: fetch.dart

import 'dart:io';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:dio/dio.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
import 'package:path_provider/path_provider.dart';


final Uri _uriHost = Uri.parse('ホスト'); // http://10.0.2.2:8000


Future fetch() async {
    final Dio dio = Dio();

    Directory appDocDir = await getApplicationDocumentsDirectory();
    String appDocPath = appDocDir.path;
    PersistCookieJar cookieJar = PersistCookieJar(storage: FileStorage(appDocPath+"/.cookies/"));
    dio.interceptors.add(CookieManager(cookieJar));
    print(await cookieJar.loadForRequest(_uriHost));

    // TODO fetchの処理
    final response = await dio.get(
          '/list-data',
          // Cookiesの認証情報をHeaderに持たせるetc........
          // options: Options(
          //  headers: {
          //    'Authorization': 'JWT ${cookieList.first.value}',
          //  },
          // ),
      );
}
6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?