見出し画像

PythonでAndroidアプリ作成してみる #7 クライアント認証 (CookieとKivy UrlRequest)

こんにちは、Rcatです。
今回はクライアントの認証をやっていきます。
バックアップサーバーは1つの端末だけでなく、複数の端末を接続できることを想定しているので、端末を見分ける必要があります。
また、既存のデータに他の端末が上書きしてしまわないようにログインのように認証する必要があります。
今回はhttpを使っているので、その辺は普通のログイン画面と同じような仕組みでやっていけると思います。
ただし、今回使っているライブラリが普通のrequestライブラリではなく、kivyUrlRequestなのでやり方を調べ直さないといけません。
それでは実験から認証までを見ていきましょう。

本シリーズはこちら


UrlRequestの特徴の把握

通常のリクエストの動作確認

前回はファイルのアップロードに専念していましたので、次は普通のリクエストなどの動作の把握をしていきます。

from kivy.network.urlrequest import UrlRequest
req = UrlRequest(url, on_success, on_redirect, on_failure, on_error,
                 on_progress, req_body, req_headers, chunk_size,
                 timeout, method, decode, debug, file_path, ca_file,
                 verify)
#https://kivy.org/doc/stable/api-kivy.network.urlrequest.html

関数の使い方を見てみるとコールバック関数がありますが、場合によってはこの方法は望ましいとは言えません。
少し見てみると、wait()で処理を停止することができるみたいです。これを使って同期的に処理を実行できないか見てみます。

def CallBack_success(req,resp):
			nonlocal ConnectStatus
			if req.result == "OK":
				ConnectStatus = True
				print(req.is_finished,req.resp_status,req.result) リクエスト完了の有無,ステータスコード,結果(TEXT)
URL = f'http://{Config.Config["server"]}:{PORT}/backup_testacces'
res = UrlRequest(url=URL,on_success=CallBack_success,timeout=5)
res.wait()
print("---WATI---")
print(res.result)

今回使用するのは上記のようなコードです。
一部変数が混じっていますが、まぁ名前でわかるでしょう。
これはコールバック関数とレスポンスを待った後のレスポンスオブジェクトから直接オブジェクトを取得する方法の両方を同時に試すコードです。

結果は下記の通りです。
まずはコールバック関数が先に呼ばれ、終了ステータス及びステータスコード、レスポンスのテキストが表示されています。
ちなみにサーバーからのレスポンスは"OK"なのでこれで合ってます。
その後、同期処理の方に進んでいます。リザルトで中身が取得できることから、コールバック関数を使っても同期処理をしてもどちらでも同じことが実現できるように思えます。

True 200 OK
---WATI---
OK

クッキーについて確認する

さて、かなり最初のネットワーク動作権当時の話ですが、複数のクライアントを見分けるためにログイン処理のようなものをしようと考えていました。
その仕組みにはログインと同じくクッキーを用いようと考えているのですが、先程から関数を見てわかる通りクッキーを乗せる引数がありません。
こちらについても確認していきましょう。

まずサーバー側です。
とりあえずこのURLにクライアント名だけ投げれば、ログインできたものとします。
ちなみに昔はセットクッキーを使って自力でクッキー管理をしていたのですが、ちゃんと調べるとセッションを管理するためのモジュールも含まれているようなので、それに挑戦してみたいと思います。
sessionというのがそのモジュールのことで、この辞書に値を追加すると自動的にクライアントにクッキー情報が送られるようになるみたいです。

クライアント側はこんな感じです。
フォームのデータを送らなければいけないので、前回アップロードで使用したテクニックを使い、フォームの情報をポストします。

これに対する応答が下記のとおりです。
新しくSet-Cookieというのが現れました。正常にログインとセッションの管理が行われているようです。

{'Content-Type': 'text/html; charset=utf-8', 'Content-Length': '2', 'Vary': 'Cookie', 'Date': 'Sun, 21 Apr 2024 05:18:22 GMT', 'Set-Cookie': 'session=eyJjbGllbnQiOiJURVNUX0NMSUVOVCJ9.ZiShng.zJAzEgBTZbZs1FyUZ9nAJ02uXZo; HttpOnly; Path=/'}

さて、クッキーを発行してもらったわけですが、これどうやって送り返すんでしょうか?
ちょいちょい調べたところ、リクエストヘッダーにこれを入れるみたいです。
というわけでログイン処理をした後に、次にテストURLにアクセスします。

サーバー側はこんな感じ。
sessionを使って管理しているので、このようにgetと押すだけでクッキーから値を取得できるみたいです。

クライアント側はこちら、今まで自力で作っていたヘッダーのところを変更し、クッキーの辞書だけを入れてみました。
問題がなければ、サーバー側でのプリントにクライアントの名前が入ってくるはずです。

結果はこんな感じ。
一番最初のログイン時に入力したクライアント名が表示されています。どうやらうまくいったようです。

クッキーまとめ

  1. サーバー側でセッションないしはセットクッキーを使ってクッキーを発行する

  2. クライアント側でレスポンスヘッダーからクッキーを抽出する
    レスポンスペッターのキーは"Set-Cookie"

  3. クライアント側のリクエストヘッダーにクッキーを含めてリクエストを行う
    リクエストヘッダーのキーは"Cookie"

以上の手順でkivy UrlRequestでもクッキーとログインの仕組みを使用できそうです。

クライアントログインの構築

さて、前段階の実験が長くなってしまいましたが、まずはクライアント認証から実装していきます。

クライアント認証の実装

それぞれ自分のフォルダーにアクセスするため、ユーザー名とパスワードを設定しておきます。

まずはサーバー側です。
こんな感じでクライアント名とパスワードを取得します。
また、事前登録などは必要なく使えるようにしたいので、新しいユーザーだった場合はその場で登録を済ませます。
ユーザー名とパスワードが一致している場合は、そのままクッキーを発行します。
USERObjというのは私が作ったユーザー用のクラスです。
詳しい中身については、今後配布を予定しているソースコードの全容をご確認ください。

次にクライアント側です。
まず、最初にクライアント認証を追加しました。
リクエストヘッダーにクライアント名とパスワードをつけてログインURLにアクセスします。
また、パスワードについては送信前にハッシュ化するようにしています。
後は先ほどの手順通りクッキーを受信してチェックURLにアクセスしています。

アクセスしてみる

とりあえずアプリ化してスマホにインストールしました。
そして、今まで使っていなかった上の入力欄を使っていきます。
適当にクライアント名とパスワードとサーバーを入力していきます。

今回はバックアップ前にリターンするようになっているので、準備ができたらバックアップ開始ボタンを押すとテストが開始されます。
結果がこちら
最下行左側がユーザー名で右側がパスワードです。
パスワードはAAAだったはずですが、ハッシュ化により全くわからない文字列になっています。こうすることで、サーバー側にパスワードは保管されますが、大元のパスワードは何だったかわからないという状態にできるわけですね。

まとめ

今回はユーザー認証とクッキーについて見ていきました。
なんとかUrlRequestライブラリでも実装の目処が立ちそうですね。
次回はファイルのアップロード部分に進んでいきます。
それではまたお会いしましょう。


情報が役に立ったと思えば、僅かでも投げ銭していただけるとありがたいです。