【PHP】 簡単なログインフォームを作成！【ログイン／ログアウト機能】

##PHPの練習に！簡単なログインフォームを作ってみよう
こんにちは。今回はPHP学習の一環として、簡単なログインフォームを作成します。（会員情報の登録は含まれていません。今回は簡易的に会員情報を設定して使用します。）
###事前準備
今回のログインフォームを作成するにあたって、セキュリティ対策のために「パスワードのハッシュ化」、「エスケープ処理」、「ハッシュ化されたパスワード」が必要です。
[こちら](https://qiita.com/t_kawai/items/7857c37daaa002b1cc70)の記事にて、パスワードをハッシュ化するプログラムについて書かれています。ここで作成するファイルは今回必要になりますので、まずはこちらの記事を読んでパスワードをハッシュ化するプログラムを作成してください。
###１．ログインフォームの作成
![ 2018-05-12 18.21.11.png](https://qiita-image-store.s3.amazonaws.com/0/254159/be9b3920-a708-d50d-204e-181ac0e7001a.png)

こちらでログインフォームを作成します。が、このファイルは```easyloginform_content.php```にて呼び出すためのもので、このファイルにアクセスしてログイン機能を体験することはできません。


```php:easyloginform_login.php

<!-- このファイルは単体では機能しません。ログイン機能を付与したいページにrequire_once();で呼び起こして使用します。今回の場合は、easyloginform_content.phpにてrequire_once()関数を使用してこのファイルを呼び起こしています。 -->
<?php 

// HTMLでのエスケープ処理をする関数を呼び出す（ファイルは[こちらの記事](https://qiita.com/t_kawai/items/7857c37daaa002b1cc70)で作成しています。）
require_once 'h.php' ;

// password_verify()関数を読み込む -> 大体の人の環境ではおそらく不要なので省略。(PHP 5 >= 5.5.0, PHP 7では標準で使用できる)詳しくはググってください

// クリックジャッキング対策をする
// クリックジャッキングとは、視覚的な錯誤を利用して、
// ユーザーの意図とは別のものをクリックさせる受動的攻撃手法
header('X-FRAME-OPTIONS: SAMEORIGIN');

// セッションを開始
// 
session_start();

// 一人目のユーザーの登録
// ユーザー名とパスワードを設定。
// 複数名分の指定ができる
$userid[] = 'admin'; //ユーザーID
$username[] = '管理者'; // お名前

// パスワード[pass1]をpassword_hash()関数でハッシュ化した文字列
// password_hash.phpのパスワードハッシュ化プログラムを使用してハッシュ化（PHP逆引きレシピ220）
// 上に紹介しているh.phpはパスワードのハッシュ化ができるプログラムです。そちらでパスワードのハッシュ化をすると以下のような文字列を得ることができます。
$hash[] = '$2y$10$MeurUlzg8gzCHKYkDMrz/.9/3eq2qxI.GyBFy65F8BFym2/YS67dq';

// 二人目のユーザーの登録
$userid[] = 'test';
$username[] = 'テスト';

// パスワード[pass2]をpassword_hash()関数でハッシュ化した文字列
$hash[] = '$2y$10$Jb/beQEUPERIYRyzsZUcT.9U9qsLqQLOXQXaKJrjlIQwRreTkKns6';

// エラーメッセージの変数を初期化
$error = '';

// 認証済みかどうかのセッション変数を初期化
if (isset($_SESSION['auth'])) {
	$_SESSION['auth'] = false;
}

if (isset($_POST['userid']) && isset($_POST['password'])) {
	foreach ($userid as $key => $value) {
		if ($_POST['userid'] === $userid[$key] &&
			// 入力されたパスワード文字列とハッシュ化済みパスワードを照合
		password_verify($_POST['password'], $hash[$key])){
			// セッション固定化攻撃を防ぐため、セッションIDを変更
			session_regenerate_id(true);
			$_SESSION['auth'] = true;
			$_SESSION['username'] = $username[$key];
			break;
		}
	}

	if ($_SESSION['auth'] === false) {
		$error = 'ユーザーIDかパスワードに誤りがあります';
	}

}
	if ($_SESSION['auth'] !== true) {
		?>
		<!DOCTYPE html>
		<html lang="ja">
		<head>
			<meta charset="UTF-8">
			<title>簡単なログインフォームを作成</title>
			<style>
				.container {
					width: 100%;
					text-align: center;
				}
			</style>
		</head>
		<body>
			<div class="container">
				<div id="login">
					<h1>認証フォーム</h1>
					<?php 
					if ($error) {
						// エラー文がセットされていれば赤色で表示
						echo '<p style="color:red;">'.h($error).'</p>';
					}
					?>
					<form action="<?php echo h($_SERVER['SCRIPT_NAME']); ?>" method="post">
						<dl>
							<dt><label for="userid">ユーザーID:</label></dt>
							<dd><input type="text" name="userid" value=""></dd>
						</dl>
						<dl>
							<dt><label for="password">パスワード：</label></dt>
							<dd><input type="password" name="password" id="password" value=""></dd>
						</dl>
						<input type="submit" name="submit" value="ログイン">
					</form>
				</div>
			</div>
		</body>
		</html>
		<?php
		// スクリプトを終了し、認証が必要なページが表示されないようにする
		exit();
	}

```

### ２．実際のログインページ＆ログインが完了したあとの画面を作成する

![ 2018-05-12 18.21.40.png](https://qiita-image-store.s3.amazonaws.com/0/254159/1f97526e-5030-9fda-5479-ebd12a554ebc.png)

このファイルにアクセスすることによって実際に機能性のあるログイン体験をすることができます。


```php:easyloginform_content.php

<?php
// 認証を要求したいページの先頭に以下を記述する
require_once './easyloginform_login.php';
 ?>

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>簡単なログインフォームを作成したい</title>
	<style>
				.container {
					width: 100%;
					text-align: center;
				}
			</style>
</head>
<body>
	<div class="container">
		<div>
				<p><?php echo h($_SESSION['username']); ?>さんいらっしゃい！</p>
				<p>ログインした方のみ閲覧できます！</p>
				<p><a href="easyloginform_logout.php">ログアウトする</a></p>
		</div>
</body>
</html>
```

###３．ログアウトする処理を作る
![ 2018-05-12 18.21.46.png](https://qiita-image-store.s3.amazonaws.com/0/254159/3f09bf82-121b-6142-d972-d9997c2ccd9d.png)


```php:easyloginform_logout.php

//ログアウト処理をするスクリプト

<?
// セッションを開始
session_start();
// セッションを破棄
$_SESSION = array();
session_destroy();
?>
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>ログアウト</title>
	<style>
		.container {
			width: 100%;
			text-align: center;
		}
	</style>
</head>
<body>
	<div class="container">
		<p>ログアウトしました</p>
		<p><a href="easyloginform_content.php">戻る</a></p>
	</div>
</body>
</html>
```

以上です。
###参考書籍
PHP逆引きレシピ第二版