DjangoのForm Wizardを使ってみる (CookieWizardView)

昨日SessionWizardViewを使ったForm Wizardをさわってみたんで、そのままCookieWizardViewに置き換えて挙動をみてみる。


SessionWizardViewとCookieWizardViewの違いはこれだけ

class SessionWizardView(WizardView):
    """
    A WizardView with pre-configured SessionStorage backend.
    """
    storage_name = 'django.contrib.formtools.wizard.storage.session.SessionStorage'


class CookieWizardView(WizardView):
    """
    A WizardView with pre-configured CookieStorage backend.
    """
    storage_name = 'django.contrib.formtools.wizard.storage.cookie.CookieStorage'


名前の通り、SessionでなくてCookieに入力値を保存する。


1つめのフォーム表示

このときのレスポンスヘッダのSet-Cookieでwizardで扱う値が署名付きで渡される

Set-Cookie:wizard_order_wizard="{\"step_files\":{}\054\"step\":\"0\"\054\"extra_data\":{}\054\"step_data\":{}}:1UPtTy:N2BCO_W5HaHPyQgG2bhUfaS_AEM"; Path=/


1つめのフォームをsubmitして2つめのフォームを表示

リクエストヘッダでcookieを渡す。
実際はcsrftokenも渡してます。

Cookie: wizard_order_wizard="{\"step_files\":{}\054\"step\":\"0\"\054\"extra_data\":{}\054\"step_data\":{}}:1UPtTy:N2BCO_W5HaHPyQgG2bhUfaS_AEM"

レスポンスで入力した値を含むcookieが渡される

Set-Cookie:wizard_order_wizard="{\"step_files\":{\"0\":{}}\054\"step\":\"1\"\054\"extra_data\":{}\054\"step_data\":{\"0\":{\"0-password\":[\"pass\"]\054\"csrfmiddlewaretoken\":[\"A7hBiVvT6p3sL5cmMU2gVrFZI7zQArEV\"]\054\"order_wizard-current_step\":[\"0\"]\054\"0-username\":[\"user\"]}}}:1UPtUZ:VpVmp6VISGsHw8iLsmQiGK4A1o4"; Path=/


2つめのフォームをsubmitして3つめのフォームを表示

リクエストヘッダ

Cookie: wizard_order_wizard="{\"step_files\":{\"0\":{}}\054\"step\":\"1\"\054\"extra_data\":{}\054\"step_data\":{\"0\":{\"0-password\":[\"pass\"]\054\"csrfmiddlewaretoken\":[\"A7hBiVvT6p3sL5cmMU2gVrFZI7zQArEV\"]\054\"order_wizard-current_step\":[\"0\"]\054\"0-username\":[\"user\"]}}}:1UPtUZ:VpVmp6VISGsHw8iLsmQiGK4A1o4"

レスポンスヘッダ

Set-Cookie:wizard_order_wizard="{\"step_files\":{\"1\":{}\054\"0\":{}}\054\"step\":\"2\"\054\"extra_data\":{}\054\"step_data\":{\"1\":{\"csrfmiddlewaretoken\":[\"A7hBiVvT6p3sL5cmMU2gVrFZI7zQArEV\"]\054\"1-prefecture\":[\"hokkaido\"]\054\"1-name\":[\"brainstorm\"]\054\"order_wizard-current_step\":[\"1\"]\054\"1-address\":[\"test\"]}\054\"0\":{\"0-password\":[\"pass\"]\054\"csrfmiddlewaretoken\":[\"A7hBiVvT6p3sL5cmMU2gVrFZI7zQArEV\"]\054\"order_wizard-current_step\":[\"0\"]\054\"0-username\":[\"user\"]}}}:1UPtVu:WasXOcmAEgWJ6Mywk5PjFeJc8-E"; Path=/


3つめのフォームをsubmitして完了画面を表示

リクエストヘッダ

Cookie: wizard_order_wizard="{\"step_files\":{\"1\":{}\054\"0\":{}}\054\"step\":\"2\"\054\"extra_data\":{}\054\"step_data\":{\"1\":{\"csrfmiddlewaretoken\":[\"A7hBiVvT6p3sL5cmMU2gVrFZI7zQArEV\"]\054\"1-prefecture\":[\"hokkaido\"]\054\"1-name\":[\"brainstorm\"]\054\"order_wizard-current_step\":[\"1\"]\054\"1-address\":[\"test\"]}\054\"0\":{\"0-password\":[\"pass\"]\054\"csrfmiddlewaretoken\":[\"A7hBiVvT6p3sL5cmMU2gVrFZI7zQArEV\"]\054\"order_wizard-current_step\":[\"0\"]\054\"0-username\":[\"user\"]}}}:1UPtVu:WasXOcmAEgWJ6Mywk5PjFeJc8-E"


レスポンスヘッダ

Set-Cookie:wizard_order_wizard="{\"step_files\":{}\054\"step\":null\054\"extra_data\":{}\054\"step_data\":{}}:1UPtWl:-xQdBZg0B4Z_CHaSLHS0qJ21Sgk"; Path=/

こうやって署名付きのcookieを受渡しして、複数ページにまたがるフォームの入力値を維持してるわけですね。

署名付きなんでcookieの改ざんが行われた場合はエラーになります。


この通り改ざんは検知できますが、盗聴は防げないので、CookieWizardViewを使う場合は、httpsじゃないとだめですね。

そしてSessionStorage見ると、cookieのdomainとかpathとかsecure属性とか指定できるようになってないので、その辺もちゃんとしたい場合はSessionStorageを自前でカスタマイズしないとだめですね、きっと。



cookieの改ざんにはEdit This Cookieを使いました
Edit This Cookie