-1

I'm setting up a ranks system on my website. (There is probably an easier way to do it) Here is what I tried.

<?php include('../core/db/server.php');

//get users group
$query = "SELECT user_group FROM users";
$result = $db->query($query);

if (isset($_SESSION['username'])) {
    if ($username['user_group'] == 'owner') {
        $_SESSION['user'] = $logged_in_user;
        $_SESSION['success'] = "You are now logged in";
        $_SESSION['loggedin'] = "logggedin session";
        $_SESSION['panel'] = $owner;
        header('location: home.php');
    }

    if ($username['user_group'] == 'admin') {
        $_SESSION['user'] = $logged_in_user;
        $_SESSION['success'] = "You are now logged in";
        $_SESSION['loggedin'] = "logggedin session";
        $_SESSION['panel'] = $admin;
        header('location: home.php');
    }

    if ($username['user_group'] == 'mod') {
        $_SESSION['user'] = $logged_in_user;
        $_SESSION['success'] = "You are now logged in";
        $_SESSION['loggedin'] = "logggedin session";
        $_SESSION['panel'] = $mod;
        header('location: home.php');
    }

    if ($username['user_group'] == 'dev') {
        $_SESSION['user'] = $logged_in_user;
        $_SESSION['success'] = "You are now logged in";
        $_SESSION['loggedin'] = "logggedin session";
        $_SESSION['panel'] = $dev;
        header('location: home.php');
    }

    if ($username['user_group'] == 'helper') {
        $_SESSION['user'] = $logged_in_user;
        $_SESSION['success'] = "You are now logged in";
        $_SESSION['loggedin'] = "logggedin session";
        $_SESSION['panel'] = $helper;
        header('location: home.php');
    }

    if ($username['user_group'] == 'builder') {
        $_SESSION['user'] = $logged_in_user;
        $_SESSION['success'] = "You are now logged in";
        $_SESSION['loggedin'] = "logggedin session";
        $_SESSION['panel'] = $builder;
        header('location: home.php');
    }

    if ($username['user_group'] == 'member') {
        $_SESSION['user'] = $logged_in_user;
        $_SESSION['success'] = "You are now logged in";
        $_SESSION['loggedin'] = "logggedin session";
        $_SESSION['panel'] = $member;
        header('location: home.php');
    }

}

And here is my server.php file for extra info. (Details included)

<?php
session_start();

// variable declaration
$username = "";
$email    = "";
$errors = array();
$_SESSION['success'] = "";

// connect to database
$db = mysqli_connect('localhost', 'root', '', 'havokcraft');

// REGISTER USER
if (isset($_POST['reg_user'])) {
    // receive all input values from the form
    $username = mysqli_real_escape_string($db, $_POST['username']);
    $email = mysqli_real_escape_string($db, $_POST['email']);
    $password_1 = mysqli_real_escape_string($db, $_POST['password_1']);
    $password_2 = mysqli_real_escape_string($db, $_POST['password_2']);

    // form validation: ensure that the form is correctly filled
    if (empty($username)) { array_push($errors, "Username is required"); }
    if (empty($email)) { array_push($errors, "Email is required"); }
    if (empty($password_1)) { array_push($errors, "Password is required"); }

    if ($password_1 != $password_2) {
        array_push($errors, "The two passwords do not match");
    }

    // register user if there are no errors in the form
    if (count($errors) == 0) {
        $password = md5($password_1);//encrypt the password before saving in the database
        $query = "INSERT INTO users (username, email, password, user_group)
                  VALUES('$username', '$email', '$password', 'member')";
        mysqli_query($db, $query);

        $_SESSION['username'] = $username;
        $_SESSION['user_group'] = $usergroup;
        $_SESSION['success'] = "You are now logged in";
        header('location: index.php');
    }

}

// ...

// LOGIN USER
if (isset($_POST['login_user'])) {
    $username = mysqli_real_escape_string($db, $_POST['username']);
    $password = mysqli_real_escape_string($db, $_POST['password']);

    if (empty($username)) {
        array_push($errors, "Username is required");
    }
    if (empty($password)) {
        array_push($errors, "Password is required");
    }

    if (count($errors) == 0) {
        $password = SHA1($password);
        $query = "SELECT * FROM users WHERE username='$username' AND password='$password'";
        $results = mysqli_query($db, $query);

        if (mysqli_num_rows($results) == 1) {
            $_SESSION['username'] = $username;
            $_SESSION['user_group'] = $usergroup;
            $_SESSION['success'] = "You are now logged in";
            header('location: index.php');
        }else {
            array_push($errors, "Wrong username/password combination");
        }
    }
}

Basically I want to set certain sessions to certain groups, its the only way I can hide links from users that are either logged in/logged out or don't have a high enough rank to visit a page.

Dharman
  • 30,962
  • 25
  • 85
  • 135
  • 1
    your code is **vulnerable to sql injection** so use only **prepared statements with parameters** see https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php Also [Escaping is not enough to prevent sql injection](https://stackoverflow.com/questions/2353666/php-is-mysql-real-escape-string-sufficient-for-cleaning-user-input) – nbk Oct 02 '20 at 17:50
  • **Warning:** You are wide open to [SQL Injections](https://stackoverflow.com/a/60496/1839439) and should use parameterized **prepared statements** instead of manually building your queries. They are provided by [PDO](https://php.net/manual/pdo.prepared-statements.php) or by [MySQLi](https://php.net/manual/mysqli.quickstart.prepared-statements.php). Never trust any kind of input! Even when your queries are executed only by trusted users, [you are still in risk of corrupting your data](http://bobby-tables.com/). [Escaping is not enough!](https://stackoverflow.com/q/5741187) – Dharman Oct 02 '20 at 19:03
  • **Never store passwords in clear text or using MD5/SHA1!** Only store password hashes created using PHP's [`password_hash()`](https://php.net/manual/en/function.password-hash.php), which you can then verify using [`password_verify()`](https://php.net/manual/en/function.password-verify.php). Take a look at this post: [How to use password_hash](https://stackoverflow.com/q/30279321/1839439) and learn more about [bcrypt & password hashing in PHP](https://stackoverflow.com/a/6337021/1839439) – Dharman Oct 02 '20 at 19:03
  • I am picking up what y'all are putting down but i am still rookie level at coding. so imma need some help with it – Phelix Fox Oct 03 '20 at 07:16
  • Ok i am useless, i do not know how to do password hashing. I don't wanna ask alot of others but can someone rewrite this for me because i only know SHA1 and MD5 for passwords and also for the group managment to set certain sessions for certain groups foe easy moderation – Phelix Fox Oct 03 '20 at 11:58
  • Why? What have you tried? What doesn't work? – Dharman Oct 03 '20 at 11:58
  • Dharman its all in the code above – Phelix Fox Oct 03 '20 at 12:01
  • i feel kinda useless – Phelix Fox Oct 03 '20 at 12:02
  • How do you use `password_hash()` and `password_verify()`? I can't see them in your code. Also, have you fixed the SQL injection already? Please show updated code – Dharman Oct 03 '20 at 12:02
  • not yet and i don't know how password hashing and verifying works. rn im using SHA1 – Phelix Fox Oct 03 '20 at 12:03
  • Instead of moping around yourself tell us what have you tried, why and what doesn't work. What research have you done? Which articles have you read? – Dharman Oct 03 '20 at 12:04
  • do you have discord? – Phelix Fox Oct 03 '20 at 12:04
  • Well, it's quite simple actually. You take the password upon registration and generate a hash which you store as is in the database and discard the password. Then when a user logs in you take the hash from DB and the password from login and use `password_verify()` to see if they match. See https://stackoverflow.com/questions/30279321/how-to-use-phps-password-hash-to-hash-and-verify-passwords?noredirect=1&lq=1 – Dharman Oct 03 '20 at 12:05
  • after logging in or registering i get this. Warning: Illegal string offset 'user_group' in C:\xampp\phpMyAdmin\htdocs\pages\index.php on line 8 Notice: Uninitialized string offset: 0 in C:\xampp\phpMyAdmin\htdocs\pages\index.php on line 8 Warning: Illegal string offset 'user_group' in C:\xampp\phpMyAdmin\htdocs\pages\index.php on line 16 Notice: Uninitialized string offset: 0 in C:\xampp\phpMyAdmin\htdocs\pages\index.php on line 16 – Phelix Fox Oct 03 '20 at 12:07
  • Warning: Illegal string offset 'user_group' in C:\xampp\phpMyAdmin\htdocs\pages\index.php on line 48 Notice: Uninitialized string offset: 0 in C:\xampp\phpMyAdmin\htdocs\pages\index.php on line 48 Warning: Illegal string offset 'user_group' in C:\xampp\phpMyAdmin\htdocs\pages\index.php on line 56 Notice: Uninitialized string offset: 0 in C:\xampp\phpMyAdmin\htdocs\pages\index.php on line 56 – Phelix Fox Oct 03 '20 at 12:07
  • How about you start fresh. Delete everything. Don't use mysqli anymore, learn PDO which is much easier. Don't try to create a full-blown application, start with something simple as receiving a form data from HTML form. Then once you understand how form submission works and how variables work, start with a next step. Create a DB connection and try to INSERT and SELECT some simple data. Once you get the hang of the basics you can then try to handle register/login forms. It looks like you need some kind of programming course. Have you tried signing up for one online? – Dharman Oct 03 '20 at 12:11
  • if been coding for 3 years and i still don't understand php. i know form handeling html and css bnut php is where i struggle. i have started over so many times. – Phelix Fox Oct 03 '20 at 12:13
  • ok lemmi try something rq – Phelix Fox Oct 03 '20 at 12:14
  • So the question is where have you tried learning PHP? I know that there's a complete mess on the internet when it comes to PHP tutorials. Have you tried to get some tutoring? – Dharman Oct 03 '20 at 12:14
  • tutorials get me nowhere, same with coda academy and those sites. I learn as i go, i can'y find a valid source to learn from. however i learn as i go. – Phelix Fox Oct 03 '20 at 12:19
  • wait if i do the password hash thing does the password column have something in it or is it empty? – Phelix Fox Oct 03 '20 at 12:19

1 Answers1

1

How to make a simple user registration and log in form?

The first thing you should consider when making user registration portal is where and how you are going to store user accounts. For this purpose we are going to use MySQL database with the following table:

CREATE TABLE IF NOT EXISTS `accounts` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `Username` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `Hash` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `UserType` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

In this table we are going to store the username and the password hash. We also have a column that will tell us the type of the account; whether it is a normal user or an admin.

Database connection

We obviously need to connect to the database and start a session. These topic are out of scope of this answer. We are going to use PDO to connect to our database which holds our new table.

<?php

session_start();

$pdo = new PDO('mysql:host=localhost;charset=utf8mb4;dbname=test', 'dbuser', 'password', [
    \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
    \PDO::ATTR_EMULATE_PREPARES => false
]);

For a more in-depth explanation of how PDO works take a look at this article: https://phpdelusions.net/pdo

Register function

We can now create a simple function that will register a user in the database. This function will accept 3 parameters: the DB connection, username, and password.

This function will create a hash of the password, then discard this password. It is a simple example, but in real-word you would probably want to add more checks and make this more foolproof.

function register(PDO $db, string $username, string $password)
{
    if (!$username || !$password) {
        throw new Exception('Username and password is required!');
    }
    $hash = password_hash($password, PASSWORD_DEFAULT);
     
    $stmt = $db->prepare('INSERT INTO accounts(Username, Hash, UserType) VALUES(?,?,?)');
    $stmt->execute([
        $username,
        $hash,
        'user' // or admin
    ]);
}

The login function

Just as we did with the registration function, we will create one function for logging in. The function will accept the same parameters, but instead of INSERT it will SELECT from the database based on the matching username.

If there is a matching record in the database and the password is verified against the stored hash then we store the user information in a session. The session will persist this information on the hard drive and it will give the user a cookie to be used when making future requests. Using that cookie PHP will open the same session each time the page is requested.

function login(PDO $db, string $username, string $password)
{
    if (!$username || !$password) {
        throw new Exception('Username and password is required!');
    }
     
    $stmt = $db->prepare('SELECT Id, Hash, UserType FROM accounts WHERE Username=?');
    $stmt->execute([ $username ]);
    $user = $stmt->fetch();
    if (!$user || !password_verify($password, $user['Hash'])) {
        throw new Exception('Username or password incorrect!');
    }

    $_SESSION['loggedUserId'] = $user['Id'];
    $_SESSION['UserType'] = $user['UserType'];
}

The full code

We can now connect all of this together and add some HTML forms. The HTML part is out of scope but you would want to keep it separate from your PHP logic. Probably in a separate file altogether.

<?php

session_start();

$pdo = new PDO('mysql:host=localhost;charset=utf8mb4;dbname=test', 'inet', '5432', [
    \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
    \PDO::ATTR_EMULATE_PREPARES => false
]);

function register(PDO $db, string $username, string $password)
{
    if (!$username || !$password) {
        throw new Exception('Username and password is required!');
    }
    $hash = password_hash($password, PASSWORD_DEFAULT);
     
    $stmt = $db->prepare('INSERT INTO accounts(Username, Hash, UserType) VALUES(?,?,?)');
    $stmt->execute([
        $username,
        $hash,
        'user' // or admin
    ]);
}

function login(PDO $db, string $username, string $password)
{
    if (!$username || !$password) {
        throw new Exception('Username and password is required!');
    }
     
    $stmt = $db->prepare('SELECT Id, Hash, UserType FROM accounts WHERE Username=?');
    $stmt->execute([ $username ]);
    $user = $stmt->fetch();
    if (!$user || !password_verify($password, $user['Hash'])) {
        throw new Exception('Username or password incorrect!');
    }

    $_SESSION['loggedUserId'] = $user['Id'];
    $_SESSION['UserType'] = $user['UserType'];
}

if (isset($_POST['register'])) {
    register($pdo, $_POST['username'], $_POST['password']);
}

if (isset($_POST['login'])) {
    login($pdo, $_POST['username'], $_POST['password']);
}

if (!isset($_SESSION['loggedUserId'])):
?>
<!-- Register form -->
<form  method="post">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" name="register" value="Register">
</form>

<!-- Login form -->
<form  method="post">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" name="login" value="Log in">
</form>
<?php
else:
echo 'Here be something after login. You are a '.$_SESSION['UserType'];
endif;

This is a very simple example of how registration and logging in works in PHP. I would not recommend to use it as-is on a live site, but for learning purposes, it should demonstrate how this functionality works.

You can build on top of it and do something when the user type is different. Show more content to more privileged users.

Dharman
  • 30,962
  • 25
  • 85
  • 135