Loowisa
Loowisa

Reputation: 15

PHP echo only echoes hashed passwords, and matching password to username from txt file

I'm having some trouble and wondered if anyone can help me. I have an assigment from school where we're supposed to create a login/register page that saves the usernames and passwords to a text file (I know you're supposed to use a database IRL but this is for the assignment). I'm having trouble with a couple of things.

First, When I try to echo $username only the hashed passwords are shown, not the usernames. I can't figure out what I'm doing wrong.

Second, I don't know how to match the username with the correct password when I'm looping for them?

Third, I don't know if I'm using $_SESSION in the right way.

I'm very new to PHP so please go easy on me.

Here's the code, thank you!:

<?php

if (isset($_POST['submit2'])) {
$anvandare = $_POST['anvandare']; //username
$losen = $_POST['losen'];//password.

$hashlosen = password_hash($losen,PASSWORD_DEFAULT);

if (!empty($anvandare) && !empty($losen)) //If neither is empty do the following:
{
    $openlogg1 = fopen('userlog.txt', 'a+'); //open userlog.txt for reading and writing.
    $path1 = 'userlog.txt';

    if (file_exists($path1))
    {
        $userdatafile = file_get_contents($path1); //Turns the file into an string.
        $userdata = explode(PHP_EOL, $userdatafile);//first explode.

        foreach ($userdata as $userlogin) {
            $userlogin = explode(';', $userlogin); //second explode.
            foreach ($userlogin as $username) {
                if ($username == $anvandare){//Checking if username exists.
                    $usertaken = true; //if it exists $usertaken is true.
                }
            }
            echo $username . "<br>"; //only shows hashed passwords.
        }
        if ($usertaken == true){ //if usertaken is true echo "username is taken".
            echo "Användarnamnet är upptaget, välj ett annat.";

        }
        else { //otherwise write username and hashed password to userlog.txt.
            fwrite($openlogg1, $anvandare .";".$hashlosen . PHP_EOL);
        }
    }

}
fclose($openlogg1);
}

if (isset($_POST['submit'])) {
$anvandare = $_POST['anvandare'];
$losen = $_POST['losen'];

$hashlosen = password_hash($losen,PASSWORD_DEFAULT);
if (!empty($anvandare) && !empty($losen)) { //If neither is empty do the following:
    $openlogg1 = fopen('userlog.txt', 'r'); //Open userlog.txt for reading.
    $path1 = 'userlog.txt';

    if (file_exists($path1)) {
        $userdatafile = file_get_contents($path1); //Turns file into string.
        $userdata = explode(PHP_EOL, $userdatafile);//first explode

        foreach ($userdata as $userlogin) {
            $userlogin = explode(';', $userlogin); //second explode.
            foreach ($userlogin as $username) {//Checking if username exists.
                if ($username == $anvandare){ //if username equals user successuser is set to true.
                    $successuser = true;
                }
            }
            echo $username . "<br>";
        }

    if ($successuser == true){ //If successuser is true check password.
        foreach ($userdata as $password) { //Looping through password array.
            if (password_verify($password, $hashlosen)) {
                $successpass = true;
            }
        }
    }
        if ($successpass == true) {
            $_SESSION['login'] = $anvandare;
            if ($_SESSION['login'] == $anvandare){
                header('Location: index.php');}
        }
        else {
            echo "Inkorrekt användarnamn eller lösenord!";
        }

    }

    fclose($openlogg1);
}

} ?>

Upvotes: 0

Views: 178

Answers (1)

Don&#39;t Panic
Don&#39;t Panic

Reputation: 41810

First

You explode each line from the file on semicolon with

$userlogin = explode(';', $userlogin);

Then iterate the resulting array with foreach

foreach ($userlogin as $username) {
    if ($username == $anvandare){//Checking if username exists.
        $usertaken = true; //if it exists $usertaken is true.
    }
}

At the end of that loop, $username will be the last item in the $userlogin array.

Since you're entering lines in the file in username;passwordhash format, that's going to be the password.

Second

When you use password verify, you should not be comparing two hashes. The first parameter is the unhashed password as entered by the user, and the second parameter is the hash from storage.

Third

You will not be able to store values in the session unless you have started it with session_start().


What I would suggest, instead of iterating the lines in the file to find the user, is to read the file into an associative array, using username as key and password hash as value.

// read the rows into an array
$userFile = file('userlog.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
// explode each row
$userRows = array_map(function($row) { return explode(';', $row); }, $userFile);
// reindex the array by username
$users = array_column($userRows, 1, 0);

This is less efficient than checking the file line by line, but really simplifies lookups.

All you need to do to see if a user exists is to check if their username exists as a key in the array.

if (isset($users[$_POST['anvandare']])) {
    // user exists
}

And to verify the password:

$successpass = password_verify($_POST['losen'], $users[$_POST['anvandare']]);

where the first parameter is the plaintext password given by the user, and the second parameter is the hashed password taken from the file row that corresponds to the given username.

Upvotes: 0

Related Questions