sql >> データベース >  >> RDS >> Mysql

ユーザーアカウント管理、役割、権限、認証PHPおよびMySQL-パート3

    これは、ユーザーアカウント管理システムの作成方法に関する一連のチュートリアルのパート3です。他の部分はここにあります:パート1、パート2。

    フォームの検証

    signup.phpページのこの時点で、フォームのフィールドに入力せずにサインアップボタンをクリックするだけでは、フィードバックは得られませんが、フォームは何もしません。それはただあなたを見つめてそこにとどまります。以前に定義したvalidateUser()関数からの$ errorsにエラーがあり、まだフォームに表示されていないため、このままです。これらのエラーは、キーと値のペアに存在します。

    たとえば、$ errors ['username']は、usernameフィールドにエラーがある場合はそれを保持します。したがって、ユーザー名エラーが存在するかどうかを確認してから、ブートストラップクラスhas-errorをユーザー名入力フィールドをラップするdiv要素に追加します。これにより、ラベルのテキストと入力枠が赤になり、エラーがあることを示します。

    ユーザー名、メールアドレス、パスワード、パスワード確認のフィールドを検証します。したがって、signup.phpファイルを開き、次の4つのフィールドを次のコードに置き換えます。

    <div class="form-group <?php echo isset($errors['username']) ? 'has-error' : '' ?>">
      <label class="control-label">Username</label>
      <input type="text" name="username" value="<?php echo $username; ?>" class="form-control">
      <?php if (isset($errors['username'])): ?>
        <span class="help-block"><?php echo $errors['username'] ?></span>
      <?php endif; ?>
    </div>
    <div class="form-group <?php echo isset($errors['email']) ? 'has-error' : '' ?>">
      <label class="control-label">Email Address</label>
      <input type="email" name="email" value="<?php echo $email; ?>" class="form-control">
      <?php if (isset($errors['email'])): ?>
        <span class="help-block"><?php echo $errors['email'] ?></span>
      <?php endif; ?>
    </div>
    <div class="form-group <?php echo isset($errors['password']) ? 'has-error' : '' ?>">
      <label class="control-label">Password</label>
      <input type="password" name="password" class="form-control">
      <?php if (isset($errors['password'])): ?>
        <span class="help-block"><?php echo $errors['password'] ?></span>
      <?php endif; ?>
    </div>
    <div class="form-group <?php echo isset($errors['passwordConf']) ? 'has-error' : '' ?>">
      <label class="control-label">Password confirmation</label>
      <input type="password" name="passwordConf" class="form-control">
      <?php if (isset($errors['passwordConf'])): ?>
        <span class="help-block"><?php echo $errors['passwordConf'] ?></span>
      <?php endif; ?>
    </div>

    各入力フィールドのすぐ下に、各フォームフィールドのエラーメッセージが条件付きで表示されています。

    三項演算子について知らなかった場合に備えて、ここに簡単な説明があります。

    <?php echo isset($errors['username']) ? 'has-error' : '' ?>

    このステートメントは基本的に、$ errors ['username']変数が値(空ではない)に設定されている場合はhas-errorを表示し、そうでない場合は空の文字列を表示することを示しています。基本的にはif-elseステートメントです。

    これで、空のフォームをクリックしてこの検証を試すことができます。きれいにフォーマットされた検証メッセージが表示されます。

    ユーザーログイン

    アプリケーションのルートフォルダに、login.phpという名前のファイルを作成します。

    login.php:

    <?php include('config.php'); ?>
    <?php include(INCLUDE_PATH . '/logic/userSignup.php'); ?>
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>UserAccounts - Login</title>
      <!-- Bootstrap CSS -->
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
      <!-- Custome styles -->
      <link rel="stylesheet" href="assets/css/style.css">
    </head>
    <body>
      <?php include(INCLUDE_PATH . "/layouts/navbar.php") ?>
      <div class="container">
        <div class="row">
          <div class="col-md-4 col-md-offset-4">
            <form class="form" action="login.php" method="post">
              <h2 class="text-center">Login</h2>
              <hr>
              <!-- display form error messages  -->
              <?php include(INCLUDE_PATH . "/layouts/messages.php") ?>
              <div class="form-group <?php echo isset($errors['username']) ? 'has-error' : '' ?>">
                <label class="control-label">Username or Email</label>
                <input type="text" name="username" id="password" value="<?php echo $username; ?>" class="form-control">
                <?php if (isset($errors['username'])): ?>
                  <span class="help-block"><?php echo $errors['username'] ?></span>
                <?php endif; ?>
              </div>
              <div class="form-group <?php echo isset($errors['password']) ? 'has-error' : '' ?>">
                <label class="control-label">Password</label>
                <input type="password" name="password" id="password" class="form-control">
                <?php if (isset($errors['password'])): ?>
                  <span class="help-block"><?php echo $errors['password'] ?></span>
                <?php endif; ?>
              </div>
              <div class="form-group">
                <button type="submit" name="login_btn" class="btn btn-success">Login</button>
              </div>
              <p>Don't have an account? <a href="signup.php">Sign up</a></p>
            </form>
          </div>
        </div>
      </div>
    <?php include(INCLUDE_PATH . "/layouts/footer.php") ?>
    

    次にuserSignup.phpを開き、ファイルの最後に次のコードを追加してユーザーにログインします。

    // ...
    
    // USER LOGIN
    if (isset($_POST['login_btn'])) {
    	// validate form values
    	$errors = validateUser($_POST, ['login_btn']);
    	$username = $_POST['username'];
    	$password = $_POST['password']; // don't escape passwords.
    
    	if (empty($errors)) {
    		$sql = "SELECT * FROM users WHERE username=? OR email=? LIMIT 1";
    		$user = getSingleRecord($sql, 'ss', [$username, $username]);
    
    		if (!empty($user)) { // if user was found
    			if (password_verify($password, $user['password'])) { // if password matches
    				// log user in
    				loginById($user['id']);
    			} else { // if password does not match
    				$_SESSION['error_msg'] = "Wrong credentials";
    			}
    		} else { // if no user found
    			$_SESSION['error_msg'] = "Wrong credentials";
    		}
    	}
    }

    ログインボタンを入力せずにクリックすると、サインアップページの場合と同じように検証メッセージがフォームに表示されます。

    次に、前に作成したユーザーアカウントの電子メールとパスワードを入力し、ログインボタンをクリックします。クレデンシャルが正しければ、ログインしてホームページにリダイレクトされます。ログインしていることを示すフラッシュメッセージが表示されます。

    しかし、ユーザーがログインしていても、ナビゲーションバーにサインアップとログインのリンクが表示されていることに気付くでしょう。これは意味がありません。ログインしたユーザー名と、ログアウトリンクのあるドロップダウンに置き換えましょう。

    navbar.phpファイルを開き、置換 これに含まれるコード:

    navbar.php:

    <!-- the whole site is wrapped in a container div to give it some margin on the sides -->
    <!-- closing container div can be found in the footer -->
    <div class="container">
      <nav class="navbar navbar-default">
        <div class="container-fluid">
          <div class="navbar-header">
            <a class="navbar-brand" href="#">UserAccounts</a>
          </div>
          <!-- <ul class="nav navbar-nav">
            <li class="active"><a href="#">Home</a></li>
            <li><a href="#">Page 1</a></li>
            <li><a href="#">Page 2</a></li>
          </ul> -->
          <ul class="nav navbar-nav navbar-right">
            <?php if (isset($_SESSION['user'])): ?>
              <li class="dropdown">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
                  <?php echo $_SESSION['user']['username'] ?> <span class="caret"></span></a>
    
                  <?php if (isAdmin($_SESSION['user']['id'])): ?>
                    <ul class="dropdown-menu">
                      <li><a href="<?php echo BASE_URL . 'admin/profile.php' ?>">Profile</a></li>
                      <li><a href="<?php echo BASE_URL . 'admin/dashboard.php' ?>">Dashboard</a></li>
                      <li role="separator" class="divider"></li>
                      <li><a href="<?php echo BASE_URL . 'logout.php' ?>" style="color: red;">Logout</a></li>
                    </ul>
                  <?php else: ?>
                    <ul class="dropdown-menu">
                      <li><a href="<?php echo BASE_URL . 'logout.php' ?>" style="color: red;">Logout</a></li>
                    </ul>
                  <?php endif; ?>
              </li>
            <?php else: ?>
              <li><a href="<?php echo BASE_URL . 'signup.php' ?>"><span class="glyphicon glyphicon-user"></span> Sign Up</a></li>
              <li><a href="<?php echo BASE_URL . 'login.php' ?>"><span class="glyphicon glyphicon-log-in"></span> Login</a></li>
            <?php endif; ?>
          </ul>
        </div>
      </nav>
    

    次に、index.phpページを更新します。まだログインしている場合は、ヘッダーが変更され、ナビゲーションバーにユーザー名が表示されます。ユーザー名をクリックすると、ログアウトリンクが記載されたドロップダウンが表示されます。それをクリックすると、logout.phpファイルがまだ作成されていないため、ページが見つかりませんと表示されます。アプリケーションのルートフォルダにそのファイルを作成しましょう。

    logout.php:

    <?php
      session_start();
      session_destroy();
      unset($_SESSION['user']);
      header("location: login.php");
    ?>

    これで、通常のユーザー認証が完了しました。次に、管理セクションである問題の核心に移ります。あなたがそれを楽しんでいることを願っています。

    現在、loginById()関数という1つの関数のみを使用してユーザーをログインしています。その関数では、ログインしているユーザーが管理ユーザーであることが判明した場合、それらはdashboard.phpファイルにリダイレクトされます。

    管理セクション

    adminフォルダー内に、dashboard.phpファイルを作成します。

    Dashboard.php:

    <?php include('../config.php') ?>
    <?php include(ROOT_PATH . '/admin/middleware.php') ?>
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>Admin</title>
      <!-- Bootstrap CSS -->
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
      <!-- Custome styles -->
      <link rel="stylesheet" href="../static/css/style.css">
    </head>
    <body>
      <?php include(INCLUDE_PATH . "/layouts/admin_navbar.php") ?>
    
      <div class="col-md-4 col-md-offset-4">
          <h1 class="text-center">Admin</h1>
          <br />
          <ul class="list-group">
            <a href="<?php echo BASE_URL . 'admin/posts/postList.php' ?>" class="list-group-item">Manage Posts</a>
            <a href="<?php echo BASE_URL . 'admin/users/userList.php' ?>" class="list-group-item">Manage Users</a>
            <a href="<?php echo BASE_URL . 'admin/roles/roleList.php' ?>" class="list-group-item">Manage Roles</a>
          </ul>
      </div>
      <?php include(INCLUDE_PATH . "/layouts/footer.php") ?>
    </body>
    </html>

    ブラウザでhttp://localhost/user-accounts/admin/dashboard.phpにアクセスすると、警告メッセージが表示されます。これは、まだ存在していない2つのファイルmiddleware.phpとadmin_navbar.phpが含まれているためです。

    ミドルウェア.phpについては、後で作業します。ただし、今のところは、管理フォルダ内に作成して空白のままにして、警告メッセージが消えて安心できるようにします。

    admin_navbar.phpについては、includes/layoutsフォルダー内に作成します。

    admin_navbar.php:

    <!-- the whole site is wrapped in a container div to give it some margin on the sides -->
    <!-- closing container div can be found in the footer -->
    <div class="container">
      <nav class="navbar navbar-inverse">
        <div class="container-fluid">
          <div class="navbar-header">
            <a class="navbar-brand" href="<?php echo BASE_URL . 'admin/dashboard.php' ?>">Dashboard</a>
          </div>
          <ul class="nav navbar-nav navbar-right">
            <?php if (isset($_SESSION['user'])): ?>
              <li><a href="<?php echo BASE_URL . 'index.php' ?>"><span class="glyphicon glyphicon-globe"></span></a></li>
              <li class="dropdown">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
                  <?php echo $_SESSION['user']['username'] . ' (' . $_SESSION['user']['role'] . ')'; ?> <span class="caret"></span></a>
                <ul class="dropdown-menu">
                  <li><a href="<?php echo BASE_URL . 'admin/users/editProfile.php' ?>">Profile</a></li>
                  <li><a href="<?php echo BASE_URL . 'admin/dashboard.php' ?>">Dashboard</a></li>
                  <li role="separator" class="divider"></li>
                  <li><a href="<?php echo BASE_URL . 'logout.php' ?>" style="color: red;">Logout</a></li>
                </ul>
              </li>
            <?php endif; ?>
          </ul>
        </div>
      </nav>
      <?php include(INCLUDE_PATH . "/layouts/messages.php") ?>
    

    ブラウザで、dashboard.phpページを今すぐ更新すると、警告メッセージが消えます。

    Dashboard.phpは管理領域ですよね?通常のユーザーがアクセスすることは想定されていません。したがって、このページにアクセスしようとしている通常のユーザーをホームページにリダイレクトする必要があります。また、管理者のユーザーと役割はまだ作成/管理していません。そのすべてがすぐに来ます。

    ここでこの部分を終了しましょう。次のパートでは、管理者ユーザーアカウントの管理とアクセス制御について説明します。

    これらのチュートリアルを楽しんでいて、もっと多くのチュートリアルが必要な場合は、友達間でチュートリアルを共有/推奨することを検討してください。これは、これをさらに作成する上で私をサポートするのに非常に長い道のりになります。

    フォローしていただきありがとうございます。次のパートでお会いしましょう。


    1. 重複する行を削除するにはどうすればよいですか?

    2. Firebaseの概要

    3. SQLCipherとgreenDAOの統合

    4. MariaDBにデータを挿入するときの「エラー1136(21S01):列数が行1の値数と一致しない」を修正