エラーメッセージの表示
#10 エラーメッセージを表示する
http://dotinstall.com/lessons/sns_php_v2/9610
を参考に
エラーがおきたときにエラーメッセージが表示されるようにする
signup.php の
HTML部分のform部分にある
<p>お名前:<input type=”text” name=”name” value=””></p>
の後ろへ
<?php echo h($err[‘name’]); ?>
を追記
<p>メールアドレス:<input type=”text” name=”email” value=””></p>
の後ろに
<?php echo h($err[‘email’]); ?>
を追記
<p>パスワード:<input type=”password” name=”password” value=””></p>
の後ろに
<?php echo h($err[‘password’]); ?>
を追記
この状態で
ページで何も記入せずに送信するとエラーがでる
ただし、以前のものをコピペしていると
$_SERVER
が
$_SEVER
となっていることがあるので注意
これを修正しないとエラーが表示されない
ただ、このままだと入力した内容が消えて面倒なので
value=”” のところを
value=”<?php echo h($name); ?>”
というようにすれば
入力した内容がそのまま保存されている状態になる
ただ、パスワードに関しては
セキュリティのため毎度入力にしている
ソースにすると
<p>お名前:<input type=”text” name=”name” value=”<?php echo h($name); ?>”><?php echo h($err[‘name’]); ?></p>
<p>メールアドレス:<input type=”text” name=”email” value=”i<?php echo h($email); ?>”>
<?php echo h($err[‘email’]); ?></p>
というように変わる
メールアドレスの形式および存在チェック
#09 エラーチェックを行おう (2)
http://dotinstall.com/lessons/sns_php_v2/9609
を参考に
メールアドレスの形式及び存在のチェック
変更するソースファイルは
signup.php のみ
メールアドレスが正しいかどうかは
filter_var()
を使う
filter_var($email,FILTER_VALIDATE_EMAIL)
で正しいか判定
正しくないか判定するには
if(!filter_var($email,FILTER_VALIDATE_EMAIL)){
}
となる
そして、もし正しくないならエラーを出す為
$err[‘email’]=’メールアドレスの形式が正しくないです’;
とする
また、すでにメールアドレスが登録済みなら
ユーザ関数 emailExists() を使って
if(emailExists($email , $dbh)){
$err[‘email’]=’このメールアドレスはすでに登録ずみです’;
}
というようにする
ユーザ関数
emailExists() は
function emailExists($email,$dbh){
}
としてDB接続して行う関数になる
この関数の中身は
$sql =”select * from users where email = :email limit 1″;
として
$sql にSQLで検索した内容を格納
$stmt =$dbh->prepare($sql);
というように
prepare() へ $sql を指定する
prepare() はデータの挿入とか削除などにつかう
次に、プレースホルダーを使うので
$stmt->execute(array(“:email”=>$email));
とexecute() 内部で配列を指定
$user =$stmt->fetch();
で$stmt からデータを fetch() でとりだして
$user へ格納
あとは return で
return $user ? true : false;
というように三項演算子で判定すればOK
CTF参考サイト(海外のがほとんど)
DEFCON CTF
http://ctftime.org/
でCTF開催予定、結果などがアーカイブされている
Hacker Japan (ハッカー ジャパン) 2013年 03月号 [雑誌]
をみて、今回興味深かったのは
CTFで戦うためにどんな準備が必要か
そして
何が必要なのかということがインタビューされていたこと
セキュリティカンファレンスが開かれているという
http://ja.avtokyo.org/projects
をみたけど、現在は
google グループ参加している人のみと言う状態のようだ
CTFはチームの最大人数はきまっているけど
最低人数はきまっていないので
1人で挑む事も可能
ただし、かなり苦戦すると思う
CTFに関係する勉強方法としては
受験や試験みたいに過去問による傾向と対策
そして
実践を通して学び、気づくことが重要とのこと
CTF TIME は twitter アカウントがあるので
フォローしてみると面白いかもしれない
今回 紹介されていたのは
ロシアチームのサイト
http://smokedchicken.org/
米CMUチームのPPPサイト
http://ppp.cylab.cmu.edu/wordpress/
オランダチームのサイト
http://eindbazen.net/
イギリスチームのサイト
http://0xbadf00d.co.uk/
shell-storm CTF repository
http://repo.shell-storm.org/repo/CTF/
CTF archive
http://captf.com/
CTF参加にあたり
英語とコミュニケーションスキルは必須で
英語ができれば海外チームとのコミュニケーションが取れるし
日本語化されていない技術情報へ
ダイレクトアクセスできるというメリットもある
日本国内で開催されているCTF
日本国内で開催されているCTF
Hacker Japan (ハッカー ジャパン) 2013年 03月号 [雑誌]
にてCTF特集があったので、しばらくはCTFの勉強
日本国内で開催されているCTFに限っても
セキュリティキャンプのCTF
SECCON
CTF-challenge
ksnctf
Flaggers
HackIT
といろいろ
CTFの問題の特徴としては
ツールに頼るだけではとけない
奇をてらった手法を使わずとける
複数分野を網羅する
問題作成者以外の人に何らかの形で解かれている
というもの
とくに、基礎として必要なものは参考になった
TCP/IP のパケットを読み解く場合でも
3ウェイハンドシェイクを知っておかないとダメだったり
wireshark でパケットデータを解析するには
解析結果からデータを正確に読み取れるようになったり
という基礎が必要になる
効率よくスキルアップするためには
CTF問題の解説サイトでいろいろ問題を解いていく
とよいようだ
読むだけでは覚えないので
仮想環境を構築し
実際にハンズオンでやってみたり
実験結果をブログに買いたりというようにすると
アウトプットもあり効率的に学習できる
ブログに書くのはちょっと…
というように公開するのは不安というなら
ローカル開発環境を構築し
そこにwordpress をインストール
そして
ここに日々の記録をつけていけば
世間に公開することなくスキルを上げることができる
また、基本的にCTFはチーム戦となるので
自分の得意分野を特化させるのも重要
CSRF対策
#07 CSRF対策を施そう
http://dotinstall.com/lessons/sns_php_v2/9607
を参考にCSRF対策を学習
今回、変更を加えるのは
signup.php になる
sha1はハッシュという技術で
暗号化とは異なる
暗号化は
鍵があれば元に戻せるけど
ハッシュは
元に戻せない
function setToken(){
}
function checkToken(){
}
というユーザー関数を作り
setToken() のほうは適当な文字列をつくり
それをセッションのほうにセットする
mt_rand()で適当な文字列を作成し
sha1() で暗号化する
これを$token に格納しておく
$token = sha1(uniqid(mt_rand(), true));
$_SESSION[‘token’]=$token;
というようになる
そしてHTML部分に
<input type=”hidden” name=”token” value=”<?php echo h($_SESSION[‘token’]); ?>”>
というように
hidden というタイプを設定することで
画面には見えないようにセットすることができる
こうしておけば php のほうで
token による判定ができるようになる
ソースをブラウザで見てみると
tokenの value が毎回変わるのを確認できる
次に、checkToken() で
セッションに入っているものが正しいか判定する
これには if を使う
if(empty($_SESSION[‘token’]) || ($_SESSION[‘token’] != $_POST[‘token’])){
で
token が空
もしくは token がPOSTされたものと一致しない場合
ときの処理になる
このときの処理は
echo “不正なPOSTが行われました”;
exit;
と表示して終了するようにする
PHP + MySQL でログイン画面作成
PHP + MySQL でログイン画面作成
#05 ログイン画面を作ろう
http://dotinstall.com/lessons/sns_php_v2/9605
を参考に
ログインチェックとログイン画面作成について学習
ログインチェックは
ログインしていないなら ログイン画面にとばすようにする
この動作をするlogin.php は
cp index.php login.php
でコピーして内容を改造していく
session_start();
if(empty($_SESSION[‘me’])){
header(‘location: ‘.SITE_URL.’login.php’);
exit;
}
で
セッションの中に me という文字があるか調べる
内のなら
header() で指定のURLへ飛ばす
今回はlogin.php に飛ばす
そして、login.php の方のheader では
header(‘location: ‘.SITE_URL);
とすることで、index.php に飛ばすことができる
こちらの login.php では
フォームを作成して
メールアドレス
パスワード
の入力欄
そして送信ボタンを作成する
もし、登録していないのであるなら
登録画面になる signup.php へのリンクもつくる
フォームはPOSTで送信する
action=”” というように空欄なのは
この
login.php 自身に送信するから
このフォームのソースは
<form action=”” method=”POST”>
<p>メールアドレス:<input type=”text” name=”email” value=””></p>
<p>パスワード:<input type=”password” name=”password” value=””></p>
<p><input type=”submit” value~”ログイン”><a href=”signup.php”>新規登録>はこちら</
a></p>
</form>
となる
次に、画面を読み込む前に
signup.php の作成を行う
#06 新規ユーザー登録画面を作ろう
http://dotinstall.com/lessons/sns_php_v2/9606
を参考に、ユーザ登録画面の作成
今後、自分でサービスを作る時にも使うので
覚えておくと後が便利
そして、このsignup.php も
cp login.php signup.php
として、ファイルをコピーしたものを改造したほうが
手間が省ける
この改造点は
すでにログイン判定はすませているので
if による判定を削除
あとはHTML部分の改造
完了したら実行してみたけど
画面が真っ白
ということで設定を変更
219行目のコメントアウトをはずし
sudo vim /etc/apache2/mods-enabled/mime.conf
で
AddHandler cgi-script .cgi .pl
へ変更
sudo vim /etc/apache2/sites-available/default
で
10行目へ
ExecCGI
を追記
Options Indexes FollowSymLinks MultiViews ExecCGI
とした
そして
AllowOverride None を
AllowOverride All へ変更し保存
sudo service apache2 restart
したものの、解決しないため
CentOSのローカル開発環境で実験したら
あっさりできた
ということで続き
フォームがPOSTされたか、そうでないかで
処理を分岐するため if を使う
if($_SERVER[‘REQUEST_METHOD’] !=’POST’){
//SCRF対策
setToken();
}else{
checkToken();
}
というようにする
フォームを投稿したときにトークンをセットしておき
そのフォームがPOSTされたときに
値が一致しているか調べる
よく使う関数の登録
よく使う関数は登録
#04 便利な関数を登録しておこう
http://dotinstall.com/lessons/sns_php_v2/9604
を参考に、ホーム画面の作成と
関数を記述した外部ファイルを作成
vim function.php
で使う関数を記述しておく
まずDB接続するのを書いておく
function connectdb(){
try{
return new POD(DSN,DB_USER,DB_PASSWORD);
}catch(POEException $e){
echo $e->getMessage();
exit;
}
}
もし、エラーがあれば
echo $e->getMessage()
で表示する
DB接続には POD オブジェクトを作成する
return new POD(DSN,DB_USER,DB_PASSWORD);
がその部分
大文字で書いてあるのは定数
次にHTML出力の時のエスケープ
htmlspecialchars() を毎回かくのは面倒なので
function h($s){
return htmlspecialchars($s,EXT_QUOTES,”UTF-8″);
}
というように作成しておく
この設定ファイルになる config.php
関数を書いた function.php ができたら
index.php を作成する
まずは、require_once()で設定ファイルなどを読み込む
require_once(‘config.php’);
require_once(‘function.php’);
このしたにHTMLで作成する
しかし、何も表示されなかったため
WordPress のインストール手順 (ubuntu 12.04 LTS)
を参考に、必要になりそうなパッケージをインストール
sudo apt-get install php5-cgi php5-mysql libphp-phpmailer php5-gd libjs-prototype libjs-scriptaculous tinymce libphp-snoopy libjs-jquery php-gettext libjs-cropper
もっとも、原因はもっと単純なミスで
require_once() で読み込むファイルを間違えていた
とりあえず、表示確認できたので
次に
以前 twitter アプリでつまづいた
ログイン画面の作成について
http://dotinstall.com/lessons/sns_php_v2/9605
を見ながら行っていく
ユーザ管理システム作成
ユーザ管理システム作成
ユーザー管理をするWebサービスを作ろう (全19回)
http://dotinstall.com/lessons/sns_php_v2
を参考に
PHP + MySQL で新規登録
ログイン
ログアウト
ホーム画面表示などを学習
まずは
ユーザ情報管理のためのDB作成
http://dotinstall.com/lessons/sns_php_v2/9602
を参考に作成
vim commands.sql として
sql ファイルを作成し内容を
メールは重複しないように unique をつけるようにし
id は自動連番にするので
id int not null auto_increment primary key;
とする
ソースにすると
create database dotinstall_sns_php;
grant all on dotinstall_sns_php.* to dbuser@localhost identified by ‘w9EtratU’;
use dotinstall_sns_php;
create table users(
id int not null auto_increment primary key,
name varchar(255),
email varchar(255) unique,
password varchar(255),
created datetime,
modified datetime
);
あとは、mysql でDB作成
mysql -u root -p < commands.sql
でsql ファイルからDBを作成
この場合パスワードを聞かれる
しかし
mysql -u root -pddpx22358 < commands.sql
というように
mysql のパスワードを -p の後に続けて書くと
そのまま実行になる
もし、テーブル作成で失敗しているのなら
データベースを一度削除してもう一度実行でOK
DB削除は
mysql -u root -p で
ログインして
drop database dotinstall_sns_php;
で削除できる
次に、設定ファイルを php で設定
共通のものは定数で作成して
分割したほうがメンテが楽
vim config.php で作成
まずは、そのまえに作成するディレクトリなども作っておく
mkdir /var/www/sns_php
cd /var/www/sns_php/
vim config.php でファイルを作成
これは
http://dotinstall.com/lessons/sns_php_v2/9603
を見ながら作成
php の定数の作成は
define() で行う
define(‘定数’,’内容’);
となる
URLとかDBへの接続はほとんど定数にする
define(‘SITE_URL’,’http://192.168.10.248/sns_php’);
というように
ローカル開発環境なのでIPを指定
そして
define(‘PASSWORD_KEY’,’xfd8sdf’);
というように
パスワードをDBに入れる時に暗号化するのに使うものを作成する
そして、エラー出力について
NOTICE 以外はすべて表示したいので
error_reporting(E_ALL & -E_NOTICE);
セッションが有効になるディレクトリも指定するため
session_set_cookie_param(0,’/sns_php/’);
として
sns_php の中だけセッションが有効になるようにする
PHP でのファイル分割
PHP でのファイル分割
#12 ファイルを分割してみよう
http://dotinstall.com/lessons/basic_php_advanced/6912
を参考に
PHPでのファイルの分割について学習
メンテなどを考えると
1つのファイルにすべて記述するのは好ましくない
このため、
クラスだけ別のファイルに書いて読み込むようにする
今回なら
vim user.class.php
として
name = $name;
$this->email = $email;
}
public function sayHi() {
echo “hi! my name is “.$this->name;
}
}
class SuperUser extends User{
public function superSayHi(){
echo ” URyyyyyyyyyyyyy!!! \n my email is “.$this->email;
}
}
というクラス部分だけ記述
そして、元の index.php の部分は
この部分は削除してOK
こうして分割されたクラスファイルを読み込むには
PHPの場合
require_once()
を使う
これは require_once(‘読み込むファイル’);
というようにする
今回は、分割したファイルを
index.php で読み込みたいので
reqire_once(‘user.class.php’);
とする
これで、分割前とおなじ結果になるなら成功
ほかにも
require()
include()
include_once()
などがあり、それぞれ挙動が異なる
require() はファイルを読み込むけど
require_once() は一度だけ読み込む
require()
は途中でエラーが起きた時エラーで強制停止する
include() はエラーで警告はだすけど実行はされる
という違いがある
PHPのクラス継承とサブクラス
クラス継承とサブクラス
#11 クラスを継承してみよう
http://dotinstall.com/lessons/basic_php_advanced/6911
を参考に
PHPでの継承とサブクラスについて学習
クラスをつくり、拡張したいときには
継承を使う
これは extends すればいい
例えば、
class User を継承して
SuperUser というクラスを作りたいのなら
class UperUser extends user{}
とする
ちなみに、継承すると
User で定義した
メンバー変数とかユーザ関数も使えるし
さらに書き換えて別の機能を実装することもできる
これが継承というもの
PHP以外にも java とかで使われる機能
あとは、クラスの中に新しい関数を用意してみた
public function superSayHi(){
echo “URyyyyyyyyyyyyyyyy !”;
}
そして
あとは実体化するため
$bob = new superUser(“bob”,”dummy@dummybob.com”);
とする
クラスは設計図
new でこのようにかくことで実体化させることができる
superUser クラスで
User クラスと同じ構造で実体化できるのは
継承により
public function __construct($name, $email) {
$this->name = $name;
$this->email = $email;
}
も受け継いでいるため
再度 コンストラクタを書く必要性がない
あとは
$bob->superSayHi();
とすれば
Uryyyyyyyyyyyyy!
と表示される
あと、継承に関しては
public
private
の他に
protected が存在する
protected で宣言したメンバー変数などは
定義したクラスや
それを継承してできたサブクラス(継承して拡張したクラスなど)
でも使える
private との違いは
private だと
作成したクラスではアクセスできるけど
これを元に作成したサブクラスでは作った変数とかが使えないというようになる
ためしに、
class User {}
の中になる
public $email;
を
protected $email;
と変更して
class SuperUser extends User{}
の中の
echo の部分を
public function superSayHi(){
echo “URyyyyyyyyyyyyyyyy !”;
}
から
public function superSayHi(){
echo ” URyyyyyyyyyyyyy!!! \n my email is “.$this->email;
}
と変更すると
URyyyyyyyyyyyyy!!! my email is dummy@dummybob.com
となり
. で連結した文字部分の
$this->email;
が表示できているのがわかる
もし、
protected ではなく private にするとエラーになる
アクセス可能な領域により使い分けることになる