【PHP】でログイン画面を作ってみた(初心者)

2021年4月21日

PHPでログイン画面を作成してみたので備忘録です。セキュリティ的に甘いところもあるのでそのまま使用しなでください。

ログイン画面

GETリクエスト   → 通常の表示
POSTリクエスト  
 入力規則(バリデーションチェック)
 ログイン情報の確認
を行います。

ログイン情報はtxtファイルで管理する仕様のため、txtファイルを読み込み、
確認をしています。

パスワードの照合は

password_verify ( string $password , string $hash ) 

このコードを使用します。これは保存されているパスワード情報がハッシュ化されているためです。

<?php 
session_start();
$errmessage = array();
if($_POST ){
    //POST情報がある時
    if(!$_POST['e']){
        $errmessage[] = "Eメールを入力してください";
    } else if(mb_strlen($_POST['e'])>200){
        $errmessage[] = "Eメールは200文字以内にしてください";
    } else if(!filter_var($_POST['e'], FILTER_VALIDATE_EMAIL)){
        $errmessage[] = "メールアドレスが不正です";
    }

    if(!$_POST['p']){
        $errmessage[] = "パスワードを入力してください";
    } else if(mb_strlen($_POST['p']) > 200){
        $errmessage[] = "パスワードは200文字以内にしてください";
    } 
    if( !$errmessage ){
        $userfile = '../userinfo.txt';
        if(file_exists($userfile)){
            $users = file_get_contents( $userfile );
            $users = explode("\n", $users);
            foreach( $users as $k => $v ) {
                $v_ary = str_getcsv($v);
                if( $v_ary[0] == $_POST['e']){
                    if( password_verify($_POST['p'],$v_ary[1]) ){
                        $_SESSION['e']= $_POST['e'];
                        $host = $_SERVER['HTTP_HOST'];
                        $uri  = rtrim(dirname($_SERVER['PHP_SELF']),  '/\\');
                        header("Location: //$host$uri/memberonly.php");
                        exit;
                    }
                }
            } 
            $errmessage[] = "ユーザー名かパスワードが不正です";
        } else {
            $errmessage[] = "ユーザーリストファイルが見つかりません";
        }
    }   
} else {
    if( isset($_SESSION['e']) && $_SESSION['e']){
        $host = $_SERVER['HTTP_HOST'];
        $uri  = rtrim(dirname($_SERVER['PHP_SELF']),  '/\\');
        header("Location: //$host$uri/memberonly.php");
        exit;
    }
    $_POST = array();
    $_POST['e'] = "";
}

?>
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/css/bootstrap.min.css" integrity="sha384-r4NyP46KrjDleawBgD5tp8Y7UzmLA05oM1iAEQ17CSuDqnUK2+k9luXQOfXJCJ4I" crossorigin="anonymous">
    <title>ログイン画面</title>
</head>
<body>
    <div class="continer">
        <div class="row justify-content-center">
            <div class="col-6">
                <h1>ログイン</h1>
                    <?php 
                        if( $errmessage ){
                            echo '<div class="alert alert-danger col-" role="alert">';
                            echo implode('<br>', $errmessage );
                            echo '</div>';
                        }
                    ?>
                <form action="./login.php" method="post">

                    <div class="mb-3">
                        <label for="e" class="form-label">ログインID</label>
                        <input type="email" class="form-control" id="e" name="e" value="<?php echo htmlspecialchars($_POST['e']) ?>" placeholder="name@example.com">
                    </div>

                    <div class="mb-3">
                        <label for="p" class="form-label">パスワード</label>
                        <input type="password" class="form-control" id="p" name="p">
                    </div>

                    <div class="mb-3">
                        <input type="submit" name="login" class="btn btn-primary mb-3" value="ログイン">
                    </div>
                </form>
                <a href="register.php">新規登録</a>
            </div>
        </div>
    </div>
</body>
</html>

ログイン後の画面

ログイン画面からの遷移してきたかを確認します。

セッションにログイン情報があれは表示、なければログイン画面に遷移します。

<?php 
session_start();
//セッション情報の有無で表示させるか遷移させるか決定する
if( !isset($_SESSION['e'])){
    $host = $_SERVER['HTTP_HOST'];
    $uri  = rtrim(dirname($_SERVER['PHP_SELF']),  '/\\');
    header("Location: //$host$uri/login.php");
    exit;
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/css/bootstrap.min.css" integrity="sha384-r4NyP46KrjDleawBgD5tp8Y7UzmLA05oM1iAEQ17CSuDqnUK2+k9luXQOfXJCJ4I" crossorigin="anonymous">

    <title>Document</title>
</head>
<body>
    <div class="container">
        <h1>メンバー専用</h1>
        <a href="logout.php">ログアウトする</a>
    </div>
</body>
</html>

ユーザー登録画面

ログイン情報の登録です。

パスワードはハッシュ化して保存しています。

$ph   = password_hash("str", PASSWORD_DEFAULT);

このコードでパスワードをハッシュ化します。

<?php 
$errmessage = array();
if($_POST ){
    //入力内容のバリデーション
    if (!$_POST['e']) {
        $errmessage[] = "Eメールを入力してください";
    } else if( strlen($_POST['e']) > 20){
        $errmessage[] = "Eメールは20文字以内にしてください";
    } else if( !filter_var($_POST['e'], FILTER_VALIDATE_EMAIL) ){
        $errmessage[] = "メールアドレスが不正です";
    }

    if (!$_POST['p']) {
        $errmessage[] = "パスワードを入力してください";
    } else if( strlen($_POST['p']) > 20){
        $errmessage[] = "パスワードは20文字以内にしてください";
    }

    if ($_POST['p'] != $_POST['p2']){
        $errmessage[] = "パスワードが一致しません";
    }
    
    $userfile = '../userinfo.txt';
    if(file_exists($userfile)){
        $users = file_get_contents( $userfile);
        $users = explode("\n", $users);
        foreach( $users as $k => $v ) {
            $v_ary = str_getcsv($v);
            if( $v_ary[0] == $_POST['e']){
                $errmessage[] = "そのEメールアドレスは登録されてます";
                break;
            }
        } 
    }
    if( !$errmessage ){
        $ph   = password_hash($_POST['p'], PASSWORD_DEFAULT);
        $line = '"' . $_POST['e'].'","' . $ph . '"'. "\n";
        $ret  = file_put_contents($userfile, $line, FILE_APPEND);

        $host = $_SERVER['HTTP_HOST'];
        $uri  = rtrim(dirname($_SERVER['PHP_SELF']),  '/\\');
        header("Location: //$host$uri/login.php");
        exit;
    }
} else {
$_POST['e'] = "";
}

?>
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/css/bootstrap.min.css" integrity="sha384-r4NyP46KrjDleawBgD5tp8Y7UzmLA05oM1iAEQ17CSuDqnUK2+k9luXQOfXJCJ4I" crossorigin="anonymous">
        <title>ユーザー登録</title>
    </head>
    <body>
        <div class="container">
            <div class="row  justify-content-center">
                <div class="col-md-6">
                    <h1>ユーザー登録</h1>
                <?php 
                    if( $errmessage ){
                        echo '<div class="alert alert-danger col-" role="alert">';
                        echo implode('<br>', $errmessage );
                        echo '</div>';
                    }
                ?>
                
                <form  action="./register.php" method="post">

                    <div class="mb-3">
                        <label for="e" class="form-label">ログインID</label>
                        <input type="email" class="form-control" id="e" name="e" value="<?php echo htmlspecialchars($_POST['e']) ?>" placeholder="name@example.com">
                    </div>

                    <div class="mb-3">
                        <label for="p" class="form-label">パスワード</label>
                        <input type="password" class="form-control" id="p" name="p">
                    </div>

                    <div class="mb-3">
                        <label for="p2" class="form-label">パスワード(確認)</label>
                        <input type="password" class="form-control" id="p2" name="p2">
                    </div>

                    <div class="mb-3">
                        <input type="submit" name="register" class="btn btn-primary mb-3" value="登録">
                    </div>
                </form>
                <a href="login.php">戻る</a>
                </div>
            </div>
        </div>
    </body>
</html>

ログアウト画面

<?php 
session_start();
$_SESSION = array();
?>

Next-k
PHP

コメントする

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)