見出し画像

(将棋ソシャゲ)PHPでログイン画面を作る。

おはようございます。将棋ソシャゲ開発運営室です。

本日は、いよいよ「将棋とソシャゲを融合したゲーム」のプログラミングを開始します。

まずは、ログイン画面を作ります。

(参考記事)

参考文献

この Qiita 記事を参考にしました。

この記事では、ユーザの新規作成機能まで作っていますが、その機能は今回実装しません。(ユーザ数が少ないので、手作業でアカウントを作って、LINEでユーザIDとパスワードを遣り取りすれば十分です。)

それ以外にも、何点か、Qiita の記事には無い変更を加えています。

また、本記事では、ログインしていない状態で、会員専用ページにアクセスがあった場合にどうするかも考えます。

プログラムコード

私が作成したプログラムは次の通りです。(データベースのパスワードは,
マスクしています。)

index.php

<?php
session_start();
$login_id = isset($_SESSION['login_id']) ? $_SESSION['login_id'] : NULL;

?>
<!DOCTYPE html>
<html lang="ja">
	<head>
		<meta charset="UTF-8">
		<title>将棋ソシャゲ</title>
	</head>
	<body>
		<h1>将棋ソシャゲ</h1>
<?php
if ($login_id !== NULL)
{
	echo "\t\tようこそ {$login_id} さん。\r\n";
}
echo "\t\t<h2>操作</h2>\r\n";
if ($login_id === NULL)
{
	echo "\t\t<p><a href=\"./login.php\">ログイン</a></p>\r\n";
}
else
{
	echo "\t\t<p><a href=\"./main.php\">盤面へ</a></p>\r\n";
	echo "\t\t<p><a href=\"./logout.php\">ログアウト</a></p>\r\n";
}
?>
	</body>
</html>

このファイルでは、ユーザのログイン状態に応じて、リンク集(メニュー)を切り替えています。また、画面にログインIDを表示しています。

login.php

<?php
session_start();
$post_login_id = isset($_POST['login_id']) ? $_POST['login_id'] : NULL;
$post_password = isset($_POST['password']) ? $_POST['password'] : NULL;

$login_mode = $post_login_id !== NULL && $post_password !== NULL;

if ($login_mode)
{
	$mysql_dsn = 'mysql:dbname=shogi_soshage;host=localhost';
	$mysql_user = 'root';
	$mysql_password = '********';

	try
	{
		$dbh = new PDO($mysql_dsn, $mysql_user, $mysql_password);

		$sql = "SELECT login_id, password FROM mast_user WHERE login_id = :login_id";
		$stmt = $dbh->prepare($sql);
		$stmt->bindValue(':login_id', $post_login_id);
		$stmt->execute();
		$user_data = $stmt->fetchAll(PDO::FETCH_ASSOC);
		if (count($user_data) === 0)
		{
			$errors[] = 'ログインIDが間違っています。';
		}
		else
		{
			if (password_verify($post_password, $user_data[0]['password']))
			{
				//DBのユーザー情報をセッションに保存
				$_SESSION['login_id'] = $user_data[0]['login_id'];
				$messages[] = 'ログインしました。';
				$login_ok = TRUE;
			}
			else
			{
				$errors[] = 'パスワードが間違っています。';
				$login_ok = FALSE;
			}
		}
	}
	catch (PDOException $e)
	{
		$errors[] = $e->getMessage();
	}
}

$dbh = NULL;
?>
<!DOCTYPE html>
<html lang="ja">
	<head>
		<meta charset="UTF-8">
		<title>将棋ソシャゲ</title>
	</head>
	<body>
		<h1>将棋ソシャゲ</h1>
		<h2>ログイン画面</h2>
		<form action="./login.php" method="post">
			<table>
			<tr><th>ログインID</th><td><input type="text" name="login_id" required></td></tr>
			<tr><th>パスワード</th><td><input type="password" name="password" required></td></tr>
			</table>
			<input type="submit" value="ログイン"><br>
		</form>
<?php
if (isset($errors))
{
	foreach ($errors as $error)
	{
		$str = htmlspecialchars($error, ENT_QUOTES, "UTF-8");
		echo "\t\t<p>{$str}</p>\r\n";
	}
}

if (isset($messages))
{
	foreach ($messages as $message)
	{
		$str = htmlspecialchars($message, ENT_QUOTES, "UTF-8");
		echo "\t\t<p>{$str}</p>\r\n";
	}
}

if ($login_mode && $login_ok)
{
	echo "\t\t<p><a href=\"./index.php\">ホーム</a></p>\r\n";
}
?>
	</body>
</html>

logout.php

<?php
session_start();
$login_id = isset($_SESSION['login_id']) ? $_SESSION['login_id'] : NULL;
$_SESSION = array();
session_destroy();
?>
<!DOCTYPE html>
<html lang="ja">
	<head>
		<meta charset="UTF-8">
		<title>将棋ソシャゲ</title>
	</head>
	<body>
		<h1>将棋ソシャゲ</h1>
<?php
if ($login_id !== NULL)
{
	echo "\t\t<p>ログアウトしました。</p>\r\n";
}
else
{
	echo "\t\t<p>ログインしていません。</p>\r\n";
}
?>
	</body>
</html>

main.php

<?php
session_start();
$login_id = isset($_SESSION['login_id']) ? $_SESSION['login_id'] : NULL;

if ($login_id === NULL)
{
    header('Location: index.php');
    exit;
}
?>
<!DOCTYPE html>
<html lang="ja">
	<head>
		<meta charset="UTF-8">
		<title>将棋ソシャゲ</title>
	</head>
	<body>
		<h1>将棋ソシャゲ</h1>
<?php
if ($login_id !== NULL)
{
	echo "\t\t<p>ようこそ {$login_id} さん。</p>\r\n";
}
?>
        <p><a href="./index.php">ホーム</a></p>
	</body>
</html>

ログインしていないユーザがこの画面にアクセスした場合は、header('Location: index.php'); で最初に来るべき画面に飛ばしています。

知らなかったこと

今回、PHPで、初めてログイン画面を作成しました。
そこで、password_verify() 関数と password_hash() 関数を知りました。前者はパスワードの照合をするための関数、後者はデータベースにパスワードを格納するための関数です。

パスワードは SHA-1 ハッシュにして格納すれば良いとばかり思っていましたが、それは現代ではセキュリティ上の問題から推奨されないらしいです。

詳しくは次の公式ドキュメントを参照してください。

(参考文献)

最後に

今回の記事は以上です。次回は盤面の表示を行います。

この記事が気に入ったらサポートをしてみませんか?