忍者ブログ

uthorofotus iruc

プログラムを組むために考えたり憶えたりした、いろいろなことを記録していきます。タイトルの読みは「ウソロフォトス イルーク」

[20]  [19]  [18]  [17]  [16]  [15]  [14]  [13]  [12]  [11]  [10

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

askeet day six:security and form validation の解説

askeetチュートリアルの6日目『セキュリティとフォームバリデーション』です。ユーザ認証やフォーム入力値のバリデーションは、どんなアプリケーションでも実装することが多いかと思います。symfonyではこれらの機能がかなり楽に実装できます。

6日目の日本語版はまだ無いようです。有志の翻訳状況はこちらです。本家英語版はこちらです。

■これまでのsymfony(Previously on symfony)
6日目ではログインしていないユーザには特定の機能へのアクセスを制限するようにします。同時にフォームのバリデーション機能(入力値チェック)も付けます。このチュートリアル内容をより理解するためには、カスタムエクステンションの解説を読んでおくと良いです。

■ログインフォームのバリデーション(Login form validation)
▽バリデーションファイル(Validation file)
バリデーションファイルはアクションごとに設定するのでapp/frontend/modules/user/validate/login.yml を作成します。

methodsの部分には、チェックをするデータの入っているメソッド(GET/POST)とキー名を指定します。namesには各キーをチェック内容を指定します。requiredは入力必須の指定で、データが入っていればokになります。nicknameは文字数の制限もかけたいので、nicknameValidatorというバリデータを設定します。nicknameValidatorは、sfStringValidatorを使って文字数制限するバリデータです。

▽エラーの扱い(Error handling)
user/loginフォームのバリデーションの結果、フォーム値が正しくなかったらform_tagで指定したアクション(user/login)の代わりにhandleErrorLoginが実行されます。もし、そのメソッドがない場合はhandleErrorが実行されます。これは、アクションクラスの継承元(sfAction)にはsfView::ERRORを返すようになっていますので、初期状態ではloginError.phpテンプレートがビューになります。今回は同じビュー(loginSuccess.php)を表示させたいので、userアクションクラスにhandleErrorLoginメソッドを設定しておきます。

▽テンプレートとヘルパー(Template error helpers)
バリデーションに失敗して再度loginSuccess.phpを表示した際、エラーメッセージを表示させます。そう言う場合はValidationヘルパーグループにあるform_errorメソッドを使用します。form_errorメソッドは、バリデーションファイルで指定したエラーメッセージを表示してくれます。

▽エラー表示形式(Style errors)
cssにエラー表示用クラス指定をします。

■ユーザ認証(Authenticate a user)
▽カスタムバリデータ(Authenticate a user)
5日目でフォームから入力したニックネームがUserテーブルに存在するかチェックしていました。やっていることはさっき設定したバリデータと同じです。このままアクションにコードを置くよりはカスタムバリデータ化して、コードを分離させます。

先ほどの app/frontend/modules/user/validate/login.yml を変更します。キー名nicknameはnicknameValidator(sfStringValidatorを使った文字数制限)とuserValidatorの2つのバリデーションをするように設定します。userValidatorで使用するバリデータクラスには、これから作成するクラス名であるmyLoginValidatorと設定します。ログインする際は、パスワードがあっているのかチェックしますので、パスワードが入っているキー名"password"をパラメータに指定します。

▽パスワードの保存(Password storage)
今まで使っていたデータベーススキーマやテストデータにはパスワードが入っていませんでしたので、今から追加します。データベースにパスワード文字列をそのまま保存するのは、もし何らかの理由でデータベースの内容が見えてしまった場合セキュリティ的によくありません。そこで、今回はSHA1のハッシュ値を使います。

    email:        varchar(100)
    sha1_password:     varchar(40)
    salt:         varchar(32)

saltについては、ここを見てください。saltとパスワード文字列を両方使わないとパスワードハッシュが生成できないということです。ただし、SHA1は高速なクラック法が見つかり安全性が下がったという話があるので、もし実稼働させる場合は他のアルゴリズムにした方がいいかもしれません。

パスワードが登録された際にパスワードのSHA1ハッシュ化と保存をしますので、Userモデルクラス(lib/model/User.php)にあるsetPasswordをオーバーライドして、そこでPHPのsha1関数を使います。4日目に、QuestionモデルクラスのsetTitleメソッドをオーバーライドし、そこでsetStrippedTitleしたのと同じ要領です。saltはランダム数+ニックネーム+メールアドレスをmd5ハッシュ(適当な文字列を作るため)して生成しています。saltを保存しないと、ログイン時にパスワードがあっているかチェックできませんのでこれも保存します。

▽テストデータにパスワードの追加(Add password in the test data)
test_data.ymlにパスワードとメールアドレスを追加します。

▽カスタムバリデータ(Custom validator)
いよいよカスタムバリデータを作成します。askeet/apps/frontend/lib/にmyLoginValidator.class.phpを作成します。キャッシュをクリアすればこのファイルも自動的に読み込まれてバリデータとして使用可能になります。ログインフォームが送信されてバリデータ処理になった際、まずinitializeメソッドが実行され、その後executeメソッドが実行されるとあります。バリデータなのにユーザの認証処理をしているのが気になりますが後で直します。

コード見ていない/動作を確かめてもないので不確かですが、initializeメソッドの初期値設定以外の使い方について少し。他のバリデータがexecuteする前にすべてのバリデータのinitializeメソッドが実行されるのではないかと思います。自バリデータの他に特定のバリデータが実行されている場合(initializeで実行フラグを立てておく)、処理の挙動を変える場合などに使えるのではないでしょうか?

※validatorが Avalidator Bvalidator Cvalidatorとある場合
1.Avalidatorのinitialize実行 (Avalidatorを組み込んだというフラグFを立てる)
2.Bvalidatorのinitialize実行
3.Cvalidatorのinitialize実行
4.Avalidatorのexecute実行
5.Bvalidatorのexecute実行
6.Cvalidatorのexecute実行 (フラグFの有無で分岐して処理が変わる)

▽アクションからコードを除去する(Remove the code from the action)
バリデータにコードを移しましたので、userアクションからコードを取り外します。

■アクセス制限(Restrict access)
モジュールディレクトリのconfig/security.ymlで、アクセス制限ができます。アクションごとにユーザ認証(is_secure)と権限(credentials)が設定出来ます。questionモジュールのアクセス制限設定が書かれていますが、add(多分createの間違い)アクションはこの前消したので、今のところ設定しても意味がありません。もし設定したのなら、http://askeet/question/create にアクセスするとユーザ認証のエラーが出るはずです。

■リファクタリングしてはどうだい?(How about a bit of refactoring?)
6日目の作業は終わったので、ふさわしくない場所にあるコードを移動するゲーム(The move-the-code-to-an-unlikely-place game)をします。
まずはログインバリデータ(myLoginValidator.class.php)から、ユーザ認証部分のコードをユーザセッションクラス(app/frontend/lib/myUser.class.phpと言うのがすでにある)に移動します。ついでにログアウト部分のコードもアクションから移動します。
ログイン中のユーザ情報をユーザセッションから取得できるようにゲッターメソッドを設定しておきます。レイアウトテンプレートもそれにあわせて修正します。

■また明日(See you Tomorrow)
7日目はcss、コンポーネント、ページのヘッダ(上部)部分の改良など、ビューの設定をします。

PR

この記事にコメントする

お名前
タイトル
文字色
メールアドレス
URL
コメント
パスワード   Vodafone絵文字 i-mode絵文字 Ezweb絵文字

この記事へのトラックバック

この記事にトラックバックする:

askeet day seven:model and view manipulation の解説 HOME askeet day five:forms and pager の解説

プロフィール

HN:
flyfront
性別:
非公開
自己紹介:
PHPプログラマ。東京でsymfonyな仕事してます。

HNはflyfrontですが、
仕事関係ではr_koike名義を使ってる場合もあります。

Wassr

カレンダー

08 2017/09 10
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

最新コメント

[01/02 通りすがり]
[10/18 flyfront]

バーコード

アクセス解析

忍者ブログ [PR]
Template by repe