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に入力値を保存する。
このときのレスポンスヘッダのSet-Cookieでwizardで扱う値が署名付きで渡される
Set-Cookie:wizard_order_wizard="{\"step_files\":{}\054\"step\":\"0\"\054\"extra_data\":{}\054\"step_data\":{}}:1UPtTy:N2BCO_W5HaHPyQgG2bhUfaS_AEM"; Path=/
リクエストヘッダで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=/
リクエストヘッダ
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=/
リクエストヘッダ
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