ログイン処理の実装

ログイン処理の実装
#12 ログイン処理を作っていこう
http://dotinstall.com/lessons/sns_php_v2/9612
を参考に
新規登録処理のあとのログイン処理について学習
その前に登録処理の動作確認
適当に名前、メールアドレス、パスワードを入力し
エラーがないのを確認したら
開発環境のサーバーで
mysql -u root -p
でログインして
use dotinstall_sns_php;
でDBを指定
select * from users;
として
今回登録したユーザが入っているならOK
また、パスワードについては暗号化されているのが確認できる
ここまでエラーが起きなければ
次のログイン処理になるけど
もしエラーが起きているのなら
HTTPステータスコード
http://www5.plala.or.jp/vaio0630/mail/st_code.htm
も見ながらデバッグする
デバッグ完了したら
login.php の編集
ソースがそのままなら
singup.php の
32行目あたりの
if ($_SERVER[‘REQUEST_METHOD’] != ‘POST’) {
から
86行目の if の終了あたりまでをコピーし
login.php の
if (!empty($_SESSION[‘me’])) {
header(‘Location: ‘.SITE_URL);
exit;
}
のしたあたりにペースト
内容はその後編集して
if ($_SERVER[‘REQUEST_METHOD’] != ‘POST’) {
// CSRF対策
setToken();
} else {
checkToken();
$email = $_POST[‘email’];
$password = $_POST[‘password’];
$dbh = connectDb();
$err = array();
if (empty($err)) {
}
}
となり、処理は新たに作成する
トークンチェックも行うので
singup.php から
<input type=”hidden” name=”token” value=”<?php echo h($_SESSION[‘token’]); ?>”>
をコピペし
login.php の
</form>
の上あたりに貼りつける
そして、signup.php で作ったユーザ関数は
今後も使うので
functions.php へコピーして
どのファイルからでも読み込んで使えるライブラリにする
書き込む場所は
function h($s){
}
のしたあたり

ユーザ登録の実装

ユーザ登録の実装
#11 ユーザーを登録しよう
http://dotinstall.com/lessons/sns_php_v2/9611
を参考にDBへユーザ情報を登録する方法を学習
singup.php を編集する
if(empty($err)){
}
の中に書いていく
登録はDBなので
$sql =”insert into users (name,email,passowrd,created,modified)
values(:name,:email,:password,now(),now())”;
としてSQLを変数へ格納する
$stmt =$dhb->prepare($sql);
として prepare() でSQLを実行
また、プレースホルダーを使うので、これにも prepare() を使う必要がある
$param = array(
“:name”=>$name,
“:email”=>$email,
“:password”=>getSha1Password($password)
);
password に関しては暗号化するので
getSha1Password($password)
としている
これは、セキュリティのことを考えてのこと
getSha1Password()
はユーザ関数
$stmt->execute($params);
でプレースホルダーにしたものを実行
終わったら、header() で指定した Location へ飛ばす
header(‘Location: ‘.SITE_URL.’.login.php’);
でログイン画面に飛ばす
ここまできたら、exit;
で正常終了
ユーザ関数の getSha1Password() は
function getSha1Password($s){
return sha1(PASSWORD_KEY.$s);
}
というようにして
config.php で指定している定数
PASSWORD_KEY と $s つまり
入力したパスワードをつなげて
sha1 で暗号化している

登録画面でエラーメッセージの表示方法

エラーメッセージの表示
#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

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からデータベースのレコードを更新、削除
#05 データの更新・削除をしてみよう
http://dotinstall.com/lessons/basic_php_advanced/6905
を参考に
データベースのレコードを更新、削除
影響を受けたレコードの数の表示を学習
PODでデバッグするときには
エラーメッセージを表示させる
var_dump($stmt->errorInfo());
が便利
今回は、更新と削除ということで
名前が n から始まる人のメルアドを
dummy
に変えてみる
これには
prepare()
内部で SQL を発行し実行すればいい
実行するのは
更新に使う update
そして where とlike をつかう
これに関しては
#10 条件付きで抽出してみよう (1)
http://dotinstall.com/lessons/basic_mysql_v2/7410
を参考にするとわかりやすい
通常、where をつかうけど
文字列で あいまいな検索をするなら
like をつかう
今回、発行するSQLは
update users set email = :email where name like :name”
この意味は
users テーブルの email を :email に変更する
変更場所は where で指定している
name が :name になっている場所
という意味
:email
:name
はプレースホルダーの ?.?の代わりなので
execute() の中で
array() で指定する
また、mysql で ~から始まるというようなときには
%をつける
今回のように
nから始まるというなら
n%
となる
なので、
execute(array(“:email”=>”dummy”,”:name”=>”n%”))
というようにする
これで、mysql -u root -p
でログインして
select * from users;
で確認すると
email カラムの内容が
dummy に変更されているのが確認できる
次に、削除について
今回はパスワードがp10 のものを削除する
削除するためのSQLは
delete を使う
削除も prepare() を使って実行する
発行するSQLは
delete from users where password =:password
これで、users テーブルの password が
:password になっているものを削除する
:password は ?のプレースホルダーの代わりなので
これも
execute() の中に array() で指定する
今回は p10 の部分を削除したいので
execute(array(“:password”=>”p10″))
これだけでも消すことはできるけど
何件削除したか表示したほうがわかりやすいので
rowCount() を使うことで、
何件削除されたかを知ることができる
これを echo で表示すればOK
echo $stmt->rowCount() .”records deleted”;
というように
PHP では . でjavascript の+のように文字列連結を
. で行えるので、
分かりやすい文章を表示できる
私の場合だと10件有ったので
10 records deleted
と表示されました

プリペアードステートメントとbindParam

プリペアードステートメントとbindParam
#04 データを挿入してみよう (2)
http://dotinstall.com/lessons/basic_php_advanced/6904
を参考に
プリペアードステートメントとbindParam
の使い方
そして
挿入されたレコードのIDの取得を学習
プリペアードステートメントの違った書き方
まず、
prepare() で
SQLを用意する
プレースホルダーには
?,?,? ではなく
:変数名,:変数名,:変数名
の方を使う
結果については、変数 $stmt に格納
ソースにすると
$stmt = $dbh->prepare(“insert into users (name,email,password) values (:name,:email,:password)”);
次に、
bindParam() を使うことで、
それぞれのプレースホルダーと変数を結びつける
bindParam(“:プレースホルダ変数”,$変数)
というように書く
今回なら
$stmt->bindParam(“:name”, $name);
$stmt->bindParam(“:email”, $email);
$stmt->bindParam(“:password”, $password);
次に、結びつけた変数に値を代入
$変数 =”代入する値”;
今回なら
$name = “n10”;
$email = “e10”;
$password = “p10″;
あとは、
execute()
を引数なしで実行すればOK
$stmt->execute();
これで、ブラウザで確認してみて
mysql -u root -p
でログインし
use blog_app;
select * from users;

代入した値が反映されていれば成功
かなり面倒な書き方だけど
データの一部だけ変更して挿入するときなどには有効な手段になる
$name=”n10″;
$email=”e10″;
$password=”p10”;
$stmt->execute();
$name = “n10x”;
$stmt->execute();
とすることで
1つ
name=n10x
で他の値は同じというものが作成される
値を変更したら
execute();
するのを忘れずに
あと、最後に insert された値のIDを知るには
lastInsertId()
を使う
これを echo で表示すればIDが表示される
これで、ページをリロードして
表示された数値と
DBで
select * from users;
で表示される id の値が同じになる
動画では44だけど
私の場合DBにそこまで書き込んでいないので
19になりました